mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Replace implementation of world info
This commit is contained in:
@@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"folders": {
|
|
||||||
"Sample Folder": [
|
|
||||||
0,
|
|
||||||
1
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"entries": {
|
|
||||||
"0": {
|
|
||||||
"uid": 0,
|
|
||||||
"title": "AAA",
|
|
||||||
"key": [ "AAA" ],
|
|
||||||
"keysecondary": [ ],
|
|
||||||
"constant": false,
|
|
||||||
"content": "AAA is a city where BBB lives.",
|
|
||||||
"comment": "AAA definition",
|
|
||||||
"selective": true
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"uid": 1,
|
|
||||||
"title": "BBB",
|
|
||||||
"key": [ "BBB" ],
|
|
||||||
"keysecondary": [ ],
|
|
||||||
"constant": false,
|
|
||||||
"content": "BBB is a 21-year old female student of CCC academy.",
|
|
||||||
"comment": "BBB definition",
|
|
||||||
"selective": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -99,7 +99,6 @@
|
|||||||
var create_save_mes_example = '';
|
var create_save_mes_example = '';
|
||||||
|
|
||||||
var timerSaveEdit;
|
var timerSaveEdit;
|
||||||
var timerKoboldSync;
|
|
||||||
var timerWorldSave;
|
var timerWorldSave;
|
||||||
var durationSaveEdit = 200;
|
var durationSaveEdit = 200;
|
||||||
//animation right menu
|
//animation right menu
|
||||||
@@ -136,12 +135,10 @@
|
|||||||
var user_avatar = 'you.png';
|
var user_avatar = 'you.png';
|
||||||
var temp = 0.5;
|
var temp = 0.5;
|
||||||
var amount_gen = 80;
|
var amount_gen = 80;
|
||||||
var kobold_world = null;
|
var world_info = null;
|
||||||
var koboldai_world_names;
|
var world_names;
|
||||||
var kobold_world_synced = false;
|
var world_info_data = null;
|
||||||
var kobold_sync_failed = false;
|
var world_info_depth = 3;
|
||||||
var kobold_is_united = false;
|
|
||||||
var kobold_world_data = null;
|
|
||||||
var imported_world_name = '';
|
var imported_world_name = '';
|
||||||
var max_context = 2048;//2048;
|
var max_context = 2048;//2048;
|
||||||
var rep_pen = 1;
|
var rep_pen = 1;
|
||||||
@@ -338,9 +335,6 @@
|
|||||||
online_status = data.result;
|
online_status = data.result;
|
||||||
if(online_status == undefined){
|
if(online_status == undefined){
|
||||||
online_status = 'no_connection';
|
online_status = 'no_connection';
|
||||||
|
|
||||||
kobold_world_synced = false;
|
|
||||||
updateWorldStatus();
|
|
||||||
}
|
}
|
||||||
if(online_status.toLowerCase().indexOf('pygmalion') != -1){
|
if(online_status.toLowerCase().indexOf('pygmalion') != -1){
|
||||||
is_pygmalion = true;
|
is_pygmalion = true;
|
||||||
@@ -353,7 +347,6 @@
|
|||||||
resultCheckStatus();
|
resultCheckStatus();
|
||||||
if(online_status !== 'no_connection'){
|
if(online_status !== 'no_connection'){
|
||||||
var checkStatusNow = setTimeout(getStatus, 3000);//getStatus();
|
var checkStatusNow = setTimeout(getStatus, 3000);//getStatus();
|
||||||
syncKoboldWorldInfo(false);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function (jqXHR, exception) {
|
error: function (jqXHR, exception) {
|
||||||
@@ -361,18 +354,12 @@
|
|||||||
console.log(jqXHR);
|
console.log(jqXHR);
|
||||||
online_status = 'no_connection';
|
online_status = 'no_connection';
|
||||||
|
|
||||||
// invalidate world info when losing connection to kobold
|
|
||||||
kobold_world_synced = false;
|
|
||||||
updateWorldStatus();
|
|
||||||
|
|
||||||
resultCheckStatus();
|
resultCheckStatus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
if(is_get_status_novel != true){
|
if(is_get_status_novel != true){
|
||||||
online_status = 'no_connection';
|
online_status = 'no_connection';
|
||||||
kobold_world_synced = false;
|
|
||||||
updateWorldStatus();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -731,6 +718,63 @@
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkWorldInfo(chat) {
|
||||||
|
if (world_info_data.entries.length == 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const messagesToLookBack = world_info_depth * 2;
|
||||||
|
let textToScan = chat.slice(0, messagesToLookBack).join('').toLowerCase();
|
||||||
|
let worldInfo = '';
|
||||||
|
let needsToScan = true;
|
||||||
|
let allActivatedEntries = new Set();
|
||||||
|
|
||||||
|
while (needsToScan) {
|
||||||
|
let activatedNow = new Set();
|
||||||
|
|
||||||
|
for (let entryUid in world_info_data.entries) {
|
||||||
|
const entry = world_info_data.entries[entryUid];
|
||||||
|
if (allActivatedEntries.has(entry.uid)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.constant) {
|
||||||
|
activatedNow.add(entry.uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(entry.key) && entry.key.length) {
|
||||||
|
primary: for (let key of entry.key) {
|
||||||
|
if (key && textToScan.includes(key.trim().toLowerCase())) {
|
||||||
|
if (entry.selective && Array.isArray(entry.keysecondary) && entry.keysecondary.length) {
|
||||||
|
secondary: for (let keysecondary of entry.keysecondary) {
|
||||||
|
if (keysecondary && textToScan.includes(keysecondary.trim().toLowerCase())) {
|
||||||
|
activatedNow.add(entry.uid);
|
||||||
|
break secondary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
activatedNow.add(entry.uid);
|
||||||
|
break primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
needsToScan = activatedNow.size > 0;
|
||||||
|
const newContents = [...activatedNow].map(x => world_info_data.entries[x]).map(x => x.content).join('\n');
|
||||||
|
worldInfo = worldInfo + newContents;
|
||||||
|
|
||||||
|
if (needsToScan) {
|
||||||
|
textToScan = newContents.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
allActivatedEntries = new Set([...allActivatedEntries, ...activatedNow]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return worldInfo;
|
||||||
|
}
|
||||||
|
|
||||||
function isHelpRequest(message) {
|
function isHelpRequest(message) {
|
||||||
const helpTokens = ['/?', '/help'];
|
const helpTokens = ['/?', '/help'];
|
||||||
return helpTokens.includes(message.trim().toLowerCase());
|
return helpTokens.includes(message.trim().toLowerCase());
|
||||||
@@ -846,7 +890,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//*********************************
|
//*********************************
|
||||||
//PRE FORMATING STRING
|
//PRE FORMATING STRING
|
||||||
//*********************************
|
//*********************************
|
||||||
@@ -992,6 +1035,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let worldInfoString = '';
|
||||||
|
|
||||||
|
if (world_info && world_info_data) {
|
||||||
|
worldInfoString = checkWorldInfo(chat2);
|
||||||
|
}
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
||||||
for (var item of chat2) {//console.log(encode("dsfs").length);
|
for (var item of chat2) {//console.log(encode("dsfs").length);
|
||||||
@@ -1145,8 +1194,7 @@
|
|||||||
|
|
||||||
var generate_data;
|
var generate_data;
|
||||||
if(main_api == 'kobold'){
|
if(main_api == 'kobold'){
|
||||||
const use_world_info = Boolean(kobold_world && kobold_world_synced);
|
var generate_data = {prompt: finalPromt, gui_settings: true,max_length: amount_gen,temperature: temp, max_context_length: max_context};
|
||||||
var generate_data = {prompt: finalPromt, gui_settings: true,max_length: amount_gen,temperature: temp, max_context_length: max_context, use_world_info};
|
|
||||||
if(preset_settings != 'gui'){
|
if(preset_settings != 'gui'){
|
||||||
|
|
||||||
var this_settings = koboldai_settings[koboldai_setting_names[preset_settings]];
|
var this_settings = koboldai_settings[koboldai_setting_names[preset_settings]];
|
||||||
@@ -1188,7 +1236,7 @@
|
|||||||
s5:this_settings.sampler_order[4],
|
s5:this_settings.sampler_order[4],
|
||||||
s6:this_settings.sampler_order[5],
|
s6:this_settings.sampler_order[5],
|
||||||
s7:this_settings.sampler_order[6],
|
s7:this_settings.sampler_order[6],
|
||||||
use_world_info: use_world_info,
|
use_world_info: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1454,9 +1502,6 @@
|
|||||||
$( "#rm_button_characters" ).children("h2").css(deselected_button_style);
|
$( "#rm_button_characters" ).children("h2").css(deselected_button_style);
|
||||||
$( "#rm_button_settings" ).children("h2").css(seleced_button_style);
|
$( "#rm_button_settings" ).children("h2").css(seleced_button_style);
|
||||||
$( "#rm_button_selected_ch" ).children("h2").css(deselected_button_style);
|
$( "#rm_button_selected_ch" ).children("h2").css(deselected_button_style);
|
||||||
|
|
||||||
// Dumb call, but won't need an interval
|
|
||||||
updateWorldStatus();
|
|
||||||
});
|
});
|
||||||
$( "#rm_button_characters" ).click(function() {
|
$( "#rm_button_characters" ).click(function() {
|
||||||
selected_button = 'characters';
|
selected_button = 'characters';
|
||||||
@@ -1763,15 +1808,15 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (popup_type === 'world_imported' && imported_world_name) {
|
if (popup_type === 'world_imported' && imported_world_name) {
|
||||||
koboldai_world_names.forEach((item, i) => {
|
world_names.forEach((item, i) => {
|
||||||
if (item === imported_world_name) {
|
if (item === imported_world_name) {
|
||||||
$('#world_info').val(i).change();
|
$('#world_info').val(i).change();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
imported_world_name = '';
|
imported_world_name = '';
|
||||||
}
|
}
|
||||||
if (popup_type === 'del_world' && kobold_world) {
|
if (popup_type === 'del_world' && world_info) {
|
||||||
deleteWorldInfo(kobold_world);
|
deleteWorldInfo(world_info);
|
||||||
}
|
}
|
||||||
if(popup_type == 'new_chat' && this_chid != undefined && menu_type != "create"){//Fix it; New chat doesn't create while open create character menu
|
if(popup_type == 'new_chat' && this_chid != undefined && menu_type != "create"){//Fix it; New chat doesn't create while open create character menu
|
||||||
clearChat();
|
clearChat();
|
||||||
@@ -2100,7 +2145,6 @@
|
|||||||
is_get_status = true;
|
is_get_status = true;
|
||||||
is_api_button_press = true;
|
is_api_button_press = true;
|
||||||
getStatus();
|
getStatus();
|
||||||
detectUnitedKobold();
|
|
||||||
clearSoftPromptsList();
|
clearSoftPromptsList();
|
||||||
getSoftPromptsList();
|
getSoftPromptsList();
|
||||||
}
|
}
|
||||||
@@ -2201,21 +2245,19 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#world_info").change(function() {
|
$("#world_info").change(async function() {
|
||||||
const selectedWorld = $('#world_info').find(":selected").val();
|
const selectedWorld = $('#world_info').find(":selected").val();
|
||||||
kobold_world_synced = false;
|
world_info = null;
|
||||||
kobold_sync_failed = false;
|
world_info_data = null;
|
||||||
kobold_world = null;
|
|
||||||
|
|
||||||
if (selectedWorld !== 'None') {
|
if (selectedWorld !== 'None') {
|
||||||
const worldIndex = Number(selectedWorld);
|
const worldIndex = Number(selectedWorld);
|
||||||
kobold_world = !isNaN(worldIndex) ? koboldai_world_names[worldIndex] : null;
|
world_info = !isNaN(worldIndex) ? world_names[worldIndex] : null;
|
||||||
|
await loadWorldInfoData();
|
||||||
}
|
}
|
||||||
|
|
||||||
hideWorldEditor();
|
hideWorldEditor();
|
||||||
syncKoboldWorldInfo(true);
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
updateWorldStatus();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$( "#settings_perset" ).change(function() {
|
$( "#settings_perset" ).change(function() {
|
||||||
@@ -2316,7 +2358,6 @@
|
|||||||
main_api = 'kobold';
|
main_api = 'kobold';
|
||||||
$('#max_context_block').css('display', 'block');
|
$('#max_context_block').css('display', 'block');
|
||||||
$('#amount_gen_block').css('display', 'block');
|
$('#amount_gen_block').css('display', 'block');
|
||||||
$('#world_info_block').css('display', 'flex');
|
|
||||||
$('#softprompt_block').css('display', 'block');
|
$('#softprompt_block').css('display', 'block');
|
||||||
}
|
}
|
||||||
if($('#main_api').find(":selected").val() == 'novel'){
|
if($('#main_api').find(":selected").val() == 'novel'){
|
||||||
@@ -2325,11 +2366,8 @@
|
|||||||
main_api = 'novel';
|
main_api = 'novel';
|
||||||
$('#max_context_block').css('display', 'none');
|
$('#max_context_block').css('display', 'none');
|
||||||
$('#amount_gen_block').css('display', 'none');
|
$('#amount_gen_block').css('display', 'none');
|
||||||
$('#world_info_block').css('display', 'none');
|
|
||||||
$('#softprompt_block').css('display', 'none');
|
$('#softprompt_block').css('display', 'none');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateWorldStatus();
|
|
||||||
}
|
}
|
||||||
async function getUserAvatars(){
|
async function getUserAvatars(){
|
||||||
const response = await fetch("/getuseravatars", {
|
const response = await fetch("/getuseravatars", {
|
||||||
@@ -2358,103 +2396,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateWorldStatus() {
|
|
||||||
if($('#world_info_block').is(':visible') && kobold_world) {
|
|
||||||
$('#world_info_edit_button').show();
|
|
||||||
$('#world_status').show();
|
|
||||||
|
|
||||||
if (kobold_world_synced) {
|
|
||||||
$("#world_status_indicator").css("background-color", "green");
|
|
||||||
$("#world_status_text").html("Synchronized with KoboldAI")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let statusText = online_status === 'no_connection'
|
|
||||||
? "Waiting for connection"
|
|
||||||
: "Synchronizing...";
|
|
||||||
|
|
||||||
if (kobold_sync_failed) {
|
|
||||||
statusText = "Synchronization failed (see console)";
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#world_status_text").html(statusText);
|
|
||||||
$("#world_status_indicator").css("background-color", "red");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kobold_is_united) {
|
|
||||||
$("#world_status_text").html('<span style="font-size:90%">KoboldAI United detected. WI may not work as intended.<br>If experiencing issues, please select "None".</span>');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$('#world_status').hide();
|
|
||||||
$('#world_info_edit_button').hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function detectUnitedKobold() {
|
|
||||||
if (!api_server || main_api !== 'kobold') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we can reach Kobold's new ui, then it should be United branch
|
|
||||||
kobold_is_united = false;
|
|
||||||
try {
|
|
||||||
const kobold_united_ui2 = api_server.replace('/api', '/new_ui');
|
|
||||||
const response = await fetch(kobold_united_ui2, { method: 'HEAD'});
|
|
||||||
|
|
||||||
if (response.ok && response.status == 200) {
|
|
||||||
kobold_is_united = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
// empty catch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function syncKoboldWorldInfo(force) {
|
|
||||||
// Don't sync if no world selected or if synced and not forcing
|
|
||||||
if (online_status === 'no_connection' || (!kobold_world && !force) || (kobold_world_synced && !force)) {
|
|
||||||
updateWorldStatus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch("/synckoboldworld", {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-CSRF-Token": token,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ "name": kobold_world })
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
const syncData = await response.json();
|
|
||||||
|
|
||||||
if (syncData.ok) {
|
|
||||||
kobold_world_synced = true;
|
|
||||||
kobold_sync_failed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syncData.busy) {
|
|
||||||
// console.log('Sync API is busy. Retrying in 3sec');
|
|
||||||
clearTimeout(timerKoboldSync);
|
|
||||||
timerKoboldSync = setTimeout(() => syncKoboldWorldInfo(force), 3000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kobold_sync_failed = true;
|
|
||||||
let responseLog = response.statusText;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var responseBody = await response.text();
|
|
||||||
responseLog += ('\n' + responseBody);
|
|
||||||
} catch {
|
|
||||||
// empty catch
|
|
||||||
}
|
|
||||||
console.error(`Sync API response: ${responseLog}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateWorldStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).on('input', '#temp', function() {
|
$(document).on('input', '#temp', function() {
|
||||||
temp = $(this).val();
|
temp = $(this).val();
|
||||||
if(isInt(temp)){
|
if(isInt(temp)){
|
||||||
@@ -2474,6 +2415,11 @@
|
|||||||
$('#max_context_counter').html( $(this).val() +' Tokens');
|
$('#max_context_counter').html( $(this).val() +' Tokens');
|
||||||
var max_contextTimer = setTimeout(saveSettings, 500);
|
var max_contextTimer = setTimeout(saveSettings, 500);
|
||||||
});
|
});
|
||||||
|
$(document).on('input', '#world_info_depth', function() {
|
||||||
|
world_info_depth = parseInt($(this).val());
|
||||||
|
$('#world_info_depth_counter').html(`${$(this).val()} Messages`);
|
||||||
|
setTimeout(saveSettings, 500);
|
||||||
|
});
|
||||||
$('#style_anchor').change(function() {
|
$('#style_anchor').change(function() {
|
||||||
style_anchor = !!$('#style_anchor').prop('checked');
|
style_anchor = !!$('#style_anchor').prop('checked');
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@@ -2605,6 +2551,7 @@
|
|||||||
if(settings.anchor_order !== undefined) anchor_order = parseInt(settings.anchor_order);
|
if(settings.anchor_order !== undefined) anchor_order = parseInt(settings.anchor_order);
|
||||||
if(settings.style_anchor !== undefined) style_anchor = !!settings.style_anchor;
|
if(settings.style_anchor !== undefined) style_anchor = !!settings.style_anchor;
|
||||||
if(settings.character_anchor !== undefined) character_anchor = !!settings.character_anchor;
|
if(settings.character_anchor !== undefined) character_anchor = !!settings.character_anchor;
|
||||||
|
if(settings.world_info_depth !== undefined) world_info_depth = parseInt(settings.world_info_depth);
|
||||||
rep_pen = settings.rep_pen;
|
rep_pen = settings.rep_pen;
|
||||||
rep_pen_size = settings.rep_pen_size;
|
rep_pen_size = settings.rep_pen_size;
|
||||||
|
|
||||||
@@ -2623,6 +2570,9 @@
|
|||||||
|
|
||||||
$('#amount_gen').val(amount_gen);
|
$('#amount_gen').val(amount_gen);
|
||||||
$('#amount_gen_counter').html(amount_gen+' Tokens');
|
$('#amount_gen_counter').html(amount_gen+' Tokens');
|
||||||
|
|
||||||
|
$('#world_info_depth_counter').html(`${world_info_depth} Messages`);
|
||||||
|
$('#world_info_depth').val(world_info_depth);
|
||||||
|
|
||||||
addZeros = "";
|
addZeros = "";
|
||||||
if(isInt(rep_pen)) addZeros = ".00";
|
if(isInt(rep_pen)) addZeros = ".00";
|
||||||
@@ -2686,20 +2636,18 @@
|
|||||||
$('#api_url_text').val(api_server);
|
$('#api_url_text').val(api_server);
|
||||||
|
|
||||||
// world info settings
|
// world info settings
|
||||||
koboldai_world_names = data.koboldai_world_names?.length ? data.koboldai_world_names : [];
|
world_names = data.world_names?.length ? data.world_names : [];
|
||||||
|
|
||||||
if(settings.kobold_world != undefined) {
|
if(settings.world_info != undefined) {
|
||||||
if (koboldai_world_names.includes(settings.kobold_world)) {
|
if (world_names.includes(settings.world_info)) {
|
||||||
kobold_world = settings.kobold_world;
|
world_info = settings.world_info;
|
||||||
kobold_world_synced = false;
|
|
||||||
kobold_sync_failed = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
koboldai_world_names.forEach((item, i) => {
|
world_names.forEach((item, i) => {
|
||||||
$('#world_info').append(`<option value='${i}'>${item}</option>`);
|
$('#world_info').append(`<option value='${i}'>${item}</option>`);
|
||||||
// preselect world if saved
|
// preselect world if saved
|
||||||
if (item == kobold_world) {
|
if (item == world_info) {
|
||||||
$('#world_info').val(i).change();
|
$('#world_info').val(i).change();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -2742,7 +2690,8 @@
|
|||||||
temp_novel: temp_novel,
|
temp_novel: temp_novel,
|
||||||
rep_pen_novel: rep_pen_novel,
|
rep_pen_novel: rep_pen_novel,
|
||||||
rep_pen_size_novel: rep_pen_size_novel,
|
rep_pen_size_novel: rep_pen_size_novel,
|
||||||
kobold_world: kobold_world,
|
world_info: world_info,
|
||||||
|
world_info_depth: world_info_depth,
|
||||||
}),
|
}),
|
||||||
beforeSend: function(){
|
beforeSend: function(){
|
||||||
|
|
||||||
@@ -2756,9 +2705,7 @@
|
|||||||
//online_status = data.result;
|
//online_status = data.result;
|
||||||
if(type === 'change_name'){
|
if(type === 'change_name'){
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
syncKoboldWorldInfo(false);
|
|
||||||
},
|
},
|
||||||
error: function (jqXHR, exception) {
|
error: function (jqXHR, exception) {
|
||||||
console.log(exception);
|
console.log(exception);
|
||||||
@@ -3246,15 +3193,15 @@
|
|||||||
|
|
||||||
if (result.ok) {
|
if (result.ok) {
|
||||||
var data = await result.json();
|
var data = await result.json();
|
||||||
koboldai_world_names = data.koboldai_world_names?.length ? data.koboldai_world_names : [];
|
world_names = data.world_names?.length ? data.world_names : [];
|
||||||
$('#world_info').find('option[value!="None"]').remove();
|
$('#world_info').find('option[value!="None"]').remove();
|
||||||
|
|
||||||
koboldai_world_names.forEach((item, i) => {
|
world_names.forEach((item, i) => {
|
||||||
$('#world_info').append(`<option value='${i}'>${item}</option>`);
|
$('#world_info').append(`<option value='${i}'>${item}</option>`);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (importedWorldName) {
|
if (importedWorldName) {
|
||||||
const indexOf = koboldai_world_names.indexOf(kobold_world);
|
const indexOf = world_names.indexOf(world_info);
|
||||||
$('#world_info').val(indexOf);
|
$('#world_info').val(indexOf);
|
||||||
|
|
||||||
popup_type = 'world_imported';
|
popup_type = 'world_imported';
|
||||||
@@ -3274,30 +3221,34 @@
|
|||||||
// World Info Editor
|
// World Info Editor
|
||||||
async function showWorldEditor() {
|
async function showWorldEditor() {
|
||||||
is_world_edit_open = true;
|
is_world_edit_open = true;
|
||||||
$('#world_popup_name').val(kobold_world);
|
$('#world_popup_name').val(world_info);
|
||||||
$('#world_popup').css('display', 'flex');
|
$('#world_popup').css('display', 'flex');
|
||||||
|
await loadWorldInfoData();
|
||||||
|
displayWorldEntries(world_info_data);
|
||||||
|
}
|
||||||
|
|
||||||
if (kobold_world) {
|
async function loadWorldInfoData() {
|
||||||
const response = await fetch("/getworldinfo", {
|
if (!world_info) {
|
||||||
method: "POST",
|
return;
|
||||||
headers: {
|
}
|
||||||
"Content-Type": "application/json",
|
|
||||||
"X-CSRF-Token": token,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ name: kobold_world })
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
const response = await fetch("/getworldinfo", {
|
||||||
kobold_world_data = await response.json();
|
method: "POST",
|
||||||
displayWorldEntries(kobold_world_data);
|
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() {
|
function hideWorldEditor() {
|
||||||
is_world_edit_open = false;
|
is_world_edit_open = false;
|
||||||
$('#world_popup').css('display', 'none');
|
$('#world_popup').css('display', 'none');
|
||||||
syncKoboldWorldInfo(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayWorldEntries(data) {
|
function displayWorldEntries(data) {
|
||||||
@@ -3323,7 +3274,7 @@
|
|||||||
keyInput.on('input', function () {
|
keyInput.on('input', function () {
|
||||||
const uid = $(this).data('uid');
|
const uid = $(this).data('uid');
|
||||||
const value = $(this).val();
|
const value = $(this).val();
|
||||||
kobold_world_data.entries[uid].key = value.split(',').map(x => x.trim()).filter(x => x);
|
world_info_data.entries[uid].key = value.split(',').map(x => x.trim()).filter(x => x);
|
||||||
saveWorldInfo();
|
saveWorldInfo();
|
||||||
});
|
});
|
||||||
keyInput.val(entry.key.join(',')).trigger('input');
|
keyInput.val(entry.key.join(',')).trigger('input');
|
||||||
@@ -3334,7 +3285,7 @@
|
|||||||
keySecondaryInput.on('input', function() {
|
keySecondaryInput.on('input', function() {
|
||||||
const uid = $(this).data('uid');
|
const uid = $(this).data('uid');
|
||||||
const value = $(this).val();
|
const value = $(this).val();
|
||||||
kobold_world_data.entries[uid].keysecondary = value.split(',').map(x => x.trim()).filter(x => x);
|
world_info_data.entries[uid].keysecondary = value.split(',').map(x => x.trim()).filter(x => x);
|
||||||
saveWorldInfo();
|
saveWorldInfo();
|
||||||
});
|
});
|
||||||
keySecondaryInput.val(entry.keysecondary.join(',')).trigger('input');
|
keySecondaryInput.val(entry.keysecondary.join(',')).trigger('input');
|
||||||
@@ -3345,7 +3296,7 @@
|
|||||||
commentInput.on('input', function() {
|
commentInput.on('input', function() {
|
||||||
const uid = $(this).data('uid');
|
const uid = $(this).data('uid');
|
||||||
const value = $(this).val();
|
const value = $(this).val();
|
||||||
kobold_world_data.entries[uid].comment = value;
|
world_info_data.entries[uid].comment = value;
|
||||||
saveWorldInfo();
|
saveWorldInfo();
|
||||||
});
|
});
|
||||||
commentInput.val(entry.comment).trigger('input');
|
commentInput.val(entry.comment).trigger('input');
|
||||||
@@ -3356,7 +3307,7 @@
|
|||||||
contentInput.on('input', function() {
|
contentInput.on('input', function() {
|
||||||
const uid = $(this).data('uid');
|
const uid = $(this).data('uid');
|
||||||
const value = $(this).val();
|
const value = $(this).val();
|
||||||
kobold_world_data.entries[uid].content = value;
|
world_info_data.entries[uid].content = value;
|
||||||
saveWorldInfo();
|
saveWorldInfo();
|
||||||
|
|
||||||
// count tokens
|
// count tokens
|
||||||
@@ -3371,7 +3322,7 @@
|
|||||||
selectiveInput.on('input', function() {
|
selectiveInput.on('input', function() {
|
||||||
const uid = $(this).data('uid');
|
const uid = $(this).data('uid');
|
||||||
const value = $(this).prop('checked');
|
const value = $(this).prop('checked');
|
||||||
kobold_world_data.entries[uid].selective = value;
|
world_info_data.entries[uid].selective = value;
|
||||||
saveWorldInfo();
|
saveWorldInfo();
|
||||||
|
|
||||||
const keysecondary = $(this).closest('.world_entry').find('.keysecondary');
|
const keysecondary = $(this).closest('.world_entry').find('.keysecondary');
|
||||||
@@ -3389,7 +3340,7 @@
|
|||||||
constantInput.on('input', function() {
|
constantInput.on('input', function() {
|
||||||
const uid = $(this).data('uid');
|
const uid = $(this).data('uid');
|
||||||
const value = $(this).prop('checked');
|
const value = $(this).prop('checked');
|
||||||
kobold_world_data.entries[uid].constant = value;
|
world_info_data.entries[uid].constant = value;
|
||||||
saveWorldInfo();
|
saveWorldInfo();
|
||||||
});
|
});
|
||||||
constantInput.prop('checked', entry.constant).trigger('input');
|
constantInput.prop('checked', entry.constant).trigger('input');
|
||||||
@@ -3415,22 +3366,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function deleteWorldInfoEntry(uid) {
|
async function deleteWorldInfoEntry(uid) {
|
||||||
if (!kobold_world_data || !('entries' in kobold_world_data)) {
|
if (!world_info_data || !('entries' in world_info_data)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete kobold_world_data.entries[uid];
|
delete world_info_data.entries[uid];
|
||||||
|
|
||||||
if ('folders' in kobold_world_data) {
|
|
||||||
for (const folderName in kobold_world_data.folders) {
|
|
||||||
const folder = kobold_world_data.folders[folderName]
|
|
||||||
const index = folder.indexOf(Number(uid));
|
|
||||||
|
|
||||||
if (index !== -1) {
|
|
||||||
folder.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWorldInfoEntry() {
|
function createWorldInfoEntry() {
|
||||||
@@ -3450,22 +3390,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const newEntry = { uid: newUid, ...newEntryTemplate };
|
const newEntry = { uid: newUid, ...newEntryTemplate };
|
||||||
kobold_world_data.entries[newUid] = newEntry;
|
world_info_data.entries[newUid] = newEntry;
|
||||||
|
|
||||||
if ('folders' in kobold_world_data) {
|
|
||||||
if (kobold_world in kobold_world_data.folders && Array.isArray(kobold_world_data.folders)) {
|
|
||||||
kobold_world_data.folders[kobold_world].push(newUid);
|
|
||||||
} else {
|
|
||||||
kobold_world_data.folders[kobold_world] = [newUid];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const entryTemplate = appendWorldEntry(newEntry);
|
const entryTemplate = appendWorldEntry(newEntry);
|
||||||
entryTemplate.get(0).scrollIntoView({behavior: 'smooth'});
|
entryTemplate.get(0).scrollIntoView({behavior: 'smooth'});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveWorldInfo(immediately) {
|
async function saveWorldInfo(immediately) {
|
||||||
if (!kobold_world || !kobold_world_data) {
|
if (!world_info || !world_info_data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3476,12 +3408,8 @@
|
|||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-CSRF-Token": token,
|
"X-CSRF-Token": token,
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ name: kobold_world, data: kobold_world_data })
|
body: JSON.stringify({ name: world_info, data: world_info_data })
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
kobold_world_synced = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (immediately) {
|
if (immediately) {
|
||||||
@@ -3493,20 +3421,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function renameWorldInfo() {
|
async function renameWorldInfo() {
|
||||||
const oldName = kobold_world;
|
const oldName = world_info;
|
||||||
const newName = $('#world_popup_name').val();
|
const newName = $('#world_popup_name').val();
|
||||||
|
|
||||||
if (oldName === newName) {
|
if (oldName === newName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
kobold_world = newName;
|
world_info = newName;
|
||||||
await saveWorldInfo(true);
|
await saveWorldInfo(true);
|
||||||
await deleteWorldInfo(oldName, newName);
|
await deleteWorldInfo(oldName, newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteWorldInfo(worldInfoName, selectWorldName) {
|
async function deleteWorldInfo(worldInfoName, selectWorldName) {
|
||||||
if (!koboldai_world_names.includes(worldInfoName)) {
|
if (!world_names.includes(worldInfoName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3522,7 +3450,7 @@
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
await updateWorldInfoList();
|
await updateWorldInfoList();
|
||||||
|
|
||||||
const selectedIndex = koboldai_world_names.indexOf(selectWorldName);
|
const selectedIndex = world_names.indexOf(selectWorldName);
|
||||||
if (selectedIndex !== -1) {
|
if (selectedIndex !== -1) {
|
||||||
$('#world_info').val(selectedIndex).change();
|
$('#world_info').val(selectedIndex).change();
|
||||||
}
|
}
|
||||||
@@ -3535,13 +3463,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFreeWorldEntryUid() {
|
function getFreeWorldEntryUid() {
|
||||||
if (!kobold_world_data || !('entries' in kobold_world_data)) {
|
if (!world_info_data || !('entries' in world_info_data)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_UID = 1_000_000; // <- should be safe enough :)
|
const MAX_UID = 1_000_000; // <- should be safe enough :)
|
||||||
for (let uid = 0; uid < MAX_UID; uid++) {
|
for (let uid = 0; uid < MAX_UID; uid++) {
|
||||||
if (uid in kobold_world_data.entries) {
|
if (uid in world_info_data.entries) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return uid;
|
return uid;
|
||||||
@@ -3554,7 +3482,7 @@
|
|||||||
const MAX_FREE_NAME = 100_000;
|
const MAX_FREE_NAME = 100_000;
|
||||||
for (let index = 1; index < MAX_FREE_NAME; index++) {
|
for (let index = 1; index < MAX_FREE_NAME; index++) {
|
||||||
const newName = `New World (${index})`;
|
const newName = `New World (${index})`;
|
||||||
if (koboldai_world_names.includes(newName)) {
|
if (world_names.includes(newName)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return newName;
|
return newName;
|
||||||
@@ -3564,19 +3492,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createNewWorldInfo() {
|
async function createNewWorldInfo() {
|
||||||
const worldInfoTemplate = { folders: {}, entries: {} };
|
const worldInfoTemplate = { entries: {} };
|
||||||
const worldInfoName = getFreeWorldName();
|
const worldInfoName = getFreeWorldName();
|
||||||
|
|
||||||
if (!worldInfoName) {
|
if (!worldInfoName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
kobold_world = worldInfoName;
|
world_info = worldInfoName;
|
||||||
kobold_world_data = { ...worldInfoTemplate };
|
world_info_data = { ...worldInfoTemplate };
|
||||||
await saveWorldInfo(true);
|
await saveWorldInfo(true);
|
||||||
await updateWorldInfoList();
|
await updateWorldInfoList();
|
||||||
|
|
||||||
const selectedIndex = koboldai_world_names.indexOf(worldInfoName);
|
const selectedIndex = world_names.indexOf(worldInfoName);
|
||||||
if (selectedIndex !== -1) {
|
if (selectedIndex !== -1) {
|
||||||
$('#world_info').val(selectedIndex).change();
|
$('#world_info').val(selectedIndex).change();
|
||||||
}
|
}
|
||||||
@@ -3590,9 +3518,9 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$('#world_popup_export').click(() => {
|
$('#world_popup_export').click(() => {
|
||||||
if (kobold_world && kobold_world_data) {
|
if (world_info && world_info_data) {
|
||||||
const jsonValue = JSON.stringify(kobold_world_data);
|
const jsonValue = JSON.stringify(world_info_data);
|
||||||
const fileName = `${kobold_world}.json`;
|
const fileName = `${world_info}.json`;
|
||||||
download(jsonValue, fileName, 'application/json');
|
download(jsonValue, fileName, 'application/json');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -3733,7 +3661,7 @@
|
|||||||
<h4>Content</h4>
|
<h4>Content</h4>
|
||||||
<h5>Text that will be inserted to the prompt upon activation.</h5>
|
<h5>Text that will be inserted to the prompt upon activation.</h5>
|
||||||
</label>
|
</label>
|
||||||
<textarea class="text_pole" name="content" rows="2" placeholder=""></textarea>
|
<textarea class="text_pole" name="content" rows="4" placeholder=""></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="world_entry_form_control world_entry_form_horizontal">
|
<div class="world_entry_form_control world_entry_form_horizontal">
|
||||||
<label class="checkbox" for="constant">
|
<label class="checkbox" for="constant">
|
||||||
@@ -3914,25 +3842,6 @@
|
|||||||
<h4>Repetition Penalty Range</h4><h5 id="rep_pen_size_counter">select</h5>
|
<h4>Repetition Penalty Range</h4><h5 id="rep_pen_size_counter">select</h5>
|
||||||
<input type="range" id="rep_pen_size" name="volume" min="0" max="2048" step="1">
|
<input type="range" id="rep_pen_size" name="volume" min="0" max="2048" step="1">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<h4 id="world_info_block">
|
|
||||||
<span>World Info</span>
|
|
||||||
<div id="world_create_button" class="right_menu_button"><h2>+Create</h2></div>
|
|
||||||
<div id="world_import_button" class="right_menu_button"><h2>+Import</h2></div>
|
|
||||||
</h4>
|
|
||||||
<h5>How to use (<a href="/notes/13" target="_blank">?</a>)</h5>
|
|
||||||
<div id="rm_world_import" class="right_menu" style="display: none;">
|
|
||||||
<form id="form_world_import" action="javascript:void(null);" method="post" enctype="multipart/form-data">
|
|
||||||
<input type="file" id="world_import_file" accept=".json" name="avatar">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<select id="world_info" class="option_select_right_menu">
|
|
||||||
<option value="None">None</option>
|
|
||||||
</select>
|
|
||||||
<input id="world_info_edit_button" type="button" value="Details">
|
|
||||||
<div id="world_status">
|
|
||||||
<div id="world_status_indicator"></div><div id="world_status_text"></div>
|
|
||||||
</div>
|
|
||||||
<div id="softprompt_block">
|
<div id="softprompt_block">
|
||||||
<h4>Soft Prompt</h4>
|
<h4>Soft Prompt</h4>
|
||||||
<h5>About soft prompts (<a href="/notes/14" target="_blank">?</a>)</h5>
|
<h5>About soft prompts (<a href="/notes/14" target="_blank">?</a>)</h5>
|
||||||
@@ -3983,6 +3892,29 @@
|
|||||||
<input id="your_name_button" type="submit" value="Change">
|
<input id="your_name_button" type="submit" value="Change">
|
||||||
</form>
|
</form>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
<div id="world_info_block">
|
||||||
|
<h3>World Info</h3>
|
||||||
|
<div id="world_info_buttons">
|
||||||
|
<div id="world_create_button" class="right_menu_button"><h4>+Create</h4></div>
|
||||||
|
<div id="world_import_button" class="right_menu_button"><h4>+Import</h4></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h5>How to use (<a href="/notes/13" target="_blank">?</a>)</h5>
|
||||||
|
<div id="rm_world_import" class="right_menu" style="display: none;">
|
||||||
|
<form id="form_world_import" action="javascript:void(null);" method="post" enctype="multipart/form-data">
|
||||||
|
<input type="file" id="world_import_file" accept=".json" name="avatar">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<select id="world_info" class="option_select_right_menu">
|
||||||
|
<option value="None">None</option>
|
||||||
|
</select>
|
||||||
|
<input id="world_info_edit_button" type="button" value="Details">
|
||||||
|
<div id="world_info_depth_block">
|
||||||
|
<h4>Scan Depth </h4><h5 id="world_info_depth_counter">select</h5>
|
||||||
|
<input type="range" id="world_info_depth" name="volume" min="1" max="5" step="1">
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
<div style="opacity:0.80">
|
<div style="opacity:0.80">
|
||||||
<h3 style='margin-bottom: 10px;'>Pro Settings</h3>
|
<h3 style='margin-bottom: 10px;'>Pro Settings</h3>
|
||||||
<div id="amount_gen_block">
|
<div id="amount_gen_block">
|
||||||
|
@@ -1165,7 +1165,7 @@ input[type=button] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#world_info {
|
#world_info {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#world_info_block {
|
#world_info_block {
|
||||||
@@ -1173,26 +1173,6 @@ input[type=button] {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#world_status{
|
|
||||||
opacity: 0.5;
|
|
||||||
margin-top: 2px;
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#world_status_indicator{
|
|
||||||
border-radius: 7px;
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
background-color: red;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#world_status_text {
|
|
||||||
margin-left: 4px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#world_import_button, #world_create_button {
|
#world_import_button, #world_create_button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -1219,7 +1199,7 @@ input[type=button] {
|
|||||||
backdrop-filter: blur(50px);
|
backdrop-filter: blur(50px);
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
height: 83vh;
|
height: 100vh;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2064;
|
z-index: 2064;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
@@ -1248,6 +1228,19 @@ input[type=button] {
|
|||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#world_info_buttons {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#world_info_depth_block {
|
||||||
|
opacity: 0.8;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#world_info_depth_block input[type="range"] {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
#entry_edit_template {
|
#entry_edit_template {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
131
public/worlds/Toaru.json
Normal file
131
public/worlds/Toaru.json
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
"entries": {
|
||||||
|
"0": {
|
||||||
|
"uid": 0,
|
||||||
|
"key": [
|
||||||
|
"Tokiwadai Middle School",
|
||||||
|
"Tokiwadai"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Place(\"Tokiwadai Middle School\")[\"prestigious girls' school\", \"females only\", \"renowned in the world\", \"requires Esper ability Level Three or higher\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"uid": 1,
|
||||||
|
"key": [
|
||||||
|
"Esper",
|
||||||
|
"Ability User",
|
||||||
|
"Level"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Category(\"Esper\")[\"psychic\", \"user of supernatural powers\", \"scientifically based\", \"emits AIM\", \"ranked by Levels of strength\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"uid": 2,
|
||||||
|
"key": [
|
||||||
|
"Anti-Skill",
|
||||||
|
"Guard"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Faction(\"Anti-Skill\")[\"police of Academy City\", \"security forces\", \"SWAT unit\", \"purple symbol\", \"blue uniform\", \"SWAT armor\", \"riot shields\", \"firearms\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"uid": 3,
|
||||||
|
"key": [
|
||||||
|
"Level 5",
|
||||||
|
"Level Five"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Category(\"Level Five Rank\")[\"highest esper level\", \"only seven people in Academy City have this rank\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"uid": 4,
|
||||||
|
"key": [
|
||||||
|
"Academy City",
|
||||||
|
"Gakuen Toshi",
|
||||||
|
"City"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Place(\"Academy City\")[\"Located west of Tokyo\", \"city of several schools\", \"most advanced city in the world\", \"scientists research on psychic powers and higher technology\", \"composed of 23 districts\", \"population over 2 millions\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"uid": 5,
|
||||||
|
"key": [
|
||||||
|
"Saten Ruiko",
|
||||||
|
"Saten",
|
||||||
|
"Ruiko",
|
||||||
|
"Saten-san"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Character(\"Saten Ruiko\")[\"Female\", \"outgoing\", \"friendly\", \"shameless\", \"Level Zero\", \"friends with: {Misaka, Uiharu, Kuroko}\", \"Student (Sakugawa Middle School)\", \"Classmate of Uiharu\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"uid": 6,
|
||||||
|
"key": [
|
||||||
|
"Misaka Mikoto",
|
||||||
|
"Misaka",
|
||||||
|
"Mikoto",
|
||||||
|
"Onee-sama"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Character(\"Misaka Mikoto\")[\"Female\", \"tsundere\", \"short tempered\", \"boyish\", \"Level Five Esper\", \"third most powerful esper of Academy City\", \"Student (Tokiwadai Middle School)\", \"Railgun\", \"Electromaster\", \"Roommate of Kuroko\", \"Friends with: {Kuroko, Uiharu, Saten}\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"7": {
|
||||||
|
"uid": 7,
|
||||||
|
"key": [
|
||||||
|
"Kuroko",
|
||||||
|
"Shirai Kuroko",
|
||||||
|
"Shirai"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Character(\"Shirai Kuroko\")[\"Female\", \"Level Four Esper\", \"Teleporter powers\", \"Student (Tokiwadai Middle School)\", \"works at Judgement with Uiharu\", \"Roommate of Misaka\", \"obsessed with Misaka\", \"calls Misaka Onee-sama\", \"Friends with: {Misaka, Uiharu, Saten}\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"8": {
|
||||||
|
"uid": 8,
|
||||||
|
"key": [
|
||||||
|
"Uihari",
|
||||||
|
"Uiharu Kazari",
|
||||||
|
"Kazari"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Character(\"Uiharu Kazari\")[\"Female\", \"works for Judgement with Kuroko\", \"expert in computers and hacking\", \"wears a flower circlet\", \"Level One\", \"friends with: {Misaka, Saten, Kuroko}\", \"Student (Sakugawa Middle School)\", \"Classmate of Saten\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
},
|
||||||
|
"9": {
|
||||||
|
"uid": 9,
|
||||||
|
"key": [
|
||||||
|
"Judgement"
|
||||||
|
],
|
||||||
|
"keysecondary": [],
|
||||||
|
"comment": "",
|
||||||
|
"content": "Faction(\"Judgement\")[\"composed of students\", \"student-based disciplinary committee\", \"tasked to maintain peace-and-order within the school system\", \"members wear armbands on right sleeves\", \"green shield symbol with white stripes\"]",
|
||||||
|
"constant": false,
|
||||||
|
"selective": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
287
server.js
287
server.js
@@ -61,7 +61,7 @@ if (is_colab && process.env.googledrive == 2){
|
|||||||
const jsonParser = express.json({limit: '100mb'});
|
const jsonParser = express.json({limit: '100mb'});
|
||||||
const urlencodedParser = express.urlencoded({extended: true, limit: '100mb'});
|
const urlencodedParser = express.urlencoded({extended: true, limit: '100mb'});
|
||||||
const baseRequestArgs = { headers: { "Content-Type": "application/json" } };
|
const baseRequestArgs = { headers: { "Content-Type": "application/json" } };
|
||||||
const directories = { worlds: 'public/KoboldAI Worlds/' };
|
const directories = { worlds: 'public/worlds/' };
|
||||||
|
|
||||||
// CSRF Protection //
|
// CSRF Protection //
|
||||||
const doubleCsrf = require('csrf-csrf').doubleCsrf;
|
const doubleCsrf = require('csrf-csrf').doubleCsrf;
|
||||||
@@ -753,7 +753,7 @@ app.post('/getsettings', jsonParser, (request, response) => { //Wintermute's cod
|
|||||||
.readdirSync(directories.worlds)
|
.readdirSync(directories.worlds)
|
||||||
.filter(file => path.extname(file).toLowerCase() === '.json')
|
.filter(file => path.extname(file).toLowerCase() === '.json')
|
||||||
.sort((a, b) => a < b);
|
.sort((a, b) => a < b);
|
||||||
const koboldai_world_names = worldFiles.map(item => path.parse(item).name);
|
const world_names = worldFiles.map(item => path.parse(item).name);
|
||||||
|
|
||||||
files.forEach(item => {
|
files.forEach(item => {
|
||||||
const file = fs.readFileSync(
|
const file = fs.readFileSync(
|
||||||
@@ -797,37 +797,12 @@ app.post('/getsettings', jsonParser, (request, response) => { //Wintermute's cod
|
|||||||
settings,
|
settings,
|
||||||
koboldai_settings,
|
koboldai_settings,
|
||||||
koboldai_setting_names,
|
koboldai_setting_names,
|
||||||
koboldai_world_names,
|
world_names,
|
||||||
novelai_settings,
|
novelai_settings,
|
||||||
novelai_setting_names
|
novelai_setting_names
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Work around to disable parallel requests to endpoint
|
|
||||||
let kobold_world_sync_busy = false;
|
|
||||||
|
|
||||||
app.post('/synckoboldworld', jsonParser, async (request, response) => {
|
|
||||||
if(!request.body) return response.sendStatus(400);
|
|
||||||
|
|
||||||
if (!api_server || kobold_world_sync_busy) {
|
|
||||||
response.send({ busy: true });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
kobold_world_sync_busy = true;
|
|
||||||
const worldName = request.body.name;
|
|
||||||
await synchronizeKoboldWorldInfo(worldName);
|
|
||||||
response.send({ ok: true });
|
|
||||||
} catch (err) {
|
|
||||||
var message = JSON.stringify(err);
|
|
||||||
console.error(`Error during world synchronization: ${message}`);
|
|
||||||
response.status(500).send(message);
|
|
||||||
} finally {
|
|
||||||
kobold_world_sync_busy = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post('/getworldinfo', jsonParser, (request, response) => {
|
app.post('/getworldinfo', jsonParser, (request, response) => {
|
||||||
if (!request.body?.name) {
|
if (!request.body?.name) {
|
||||||
return response.sendStatus(400);
|
return response.sendStatus(400);
|
||||||
@@ -835,7 +810,7 @@ app.post('/getworldinfo', jsonParser, (request, response) => {
|
|||||||
|
|
||||||
const file = readWorldInfoFile(request.body.name);
|
const file = readWorldInfoFile(request.body.name);
|
||||||
|
|
||||||
return response.send(file.tavernWorldInfo);
|
return response.send(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post('/deleteworldinfo', jsonParser, (request, response) => {
|
app.post('/deleteworldinfo', jsonParser, (request, response) => {
|
||||||
@@ -856,6 +831,23 @@ app.post('/deleteworldinfo', jsonParser, (request, response) => {
|
|||||||
return response.sendStatus(200);
|
return response.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function readWorldInfoFile(worldInfoName) {
|
||||||
|
if (!worldInfoName) {
|
||||||
|
return { entries: {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
const filename = `${worldInfoName}.json`;
|
||||||
|
const pathToWorldInfo = path.join(directories.worlds, filename);
|
||||||
|
|
||||||
|
if (!fs.existsSync(pathToWorldInfo)) {
|
||||||
|
throw new Error(`World info file ${filename} doesn't exist.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const worldInfoText = fs.readFileSync(pathToWorldInfo, 'utf8');
|
||||||
|
const worldInfo = JSON.parse(worldInfoText);
|
||||||
|
return worldInfo;
|
||||||
|
}
|
||||||
|
|
||||||
function getCharaterFile(directories,response,i){ //old need del
|
function getCharaterFile(directories,response,i){ //old need del
|
||||||
if(directories.length > i){
|
if(directories.length > i){
|
||||||
|
|
||||||
@@ -1286,234 +1278,6 @@ app.post('/editworldinfo', jsonParser, (request, response) => {
|
|||||||
return response.send({ ok: true });
|
return response.send({ ok: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
function findTavernWorldEntry(info, key, content) {
|
|
||||||
for (const entryId in info.entries) {
|
|
||||||
const entry = info.entries[entryId];
|
|
||||||
const keyString = entry.key.join(',');
|
|
||||||
|
|
||||||
if (keyString === key && entry.content === content) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function synchronizeKoboldWorldInfo(worldInfoName) {
|
|
||||||
const { koboldFolderName, tavernWorldInfo } = readWorldInfoFile(worldInfoName);
|
|
||||||
|
|
||||||
// Get existing world info
|
|
||||||
const koboldWorldInfo = await getAsync(`${api_server}/v1/world_info`, baseRequestArgs);
|
|
||||||
|
|
||||||
// Validate kobold world info
|
|
||||||
let {
|
|
||||||
shouldCreateWorld,
|
|
||||||
koboldWorldUid,
|
|
||||||
tavernEntriesToCreate,
|
|
||||||
koboldEntriesToDelete,
|
|
||||||
koboldFoldersToDelete,
|
|
||||||
} = await validateKoboldWorldInfo(koboldFolderName, koboldWorldInfo, tavernWorldInfo);
|
|
||||||
|
|
||||||
// Create folder if not already exists
|
|
||||||
if (koboldFolderName && shouldCreateWorld) {
|
|
||||||
koboldWorldUid = await createKoboldFolder(koboldFolderName, tavernEntriesToCreate, tavernWorldInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
await deleteKoboldFolders(koboldFoldersToDelete);
|
|
||||||
await deleteKoboldEntries(koboldEntriesToDelete);
|
|
||||||
await createTavernEntries(tavernEntriesToCreate, koboldWorldUid, tavernWorldInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
function readWorldInfoFile(worldInfoName) {
|
|
||||||
if (!worldInfoName) {
|
|
||||||
return { koboldFolderName: null, tavernWorldInfo: { entries: {}, folders: {} }};
|
|
||||||
}
|
|
||||||
|
|
||||||
const koboldFolderName = getKoboldWorldInfoName(worldInfoName);
|
|
||||||
const filename = `${worldInfoName}.json`;
|
|
||||||
const pathToWorldInfo = path.join(directories.worlds, filename);
|
|
||||||
|
|
||||||
if (!fs.existsSync(pathToWorldInfo)) {
|
|
||||||
throw new Error(`World info file ${filename} doesn't exist.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const tavernWorldInfoText = fs.readFileSync(pathToWorldInfo, 'utf8');
|
|
||||||
const tavernWorldInfo = JSON.parse(tavernWorldInfoText);
|
|
||||||
return { koboldFolderName, tavernWorldInfo };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createKoboldFolder(koboldFolderName, tavernEntriesToCreate, tavernWorldInfo) {
|
|
||||||
const createdFolder = await postAsync(`${api_server}/v1/world_info/folders`, { data: {}, ...baseRequestArgs });
|
|
||||||
const koboldWorldUid = createdFolder.uid;
|
|
||||||
|
|
||||||
// Set a name so we could find the folder later
|
|
||||||
const setNameArgs = { data: { value: koboldFolderName }, ...baseRequestArgs };
|
|
||||||
await putAsync(`${api_server}/v1/world_info/folders/${koboldWorldUid}/name`, setNameArgs);
|
|
||||||
|
|
||||||
// Create all world info entries
|
|
||||||
tavernEntriesToCreate.push(...Object.keys(tavernWorldInfo.entries));
|
|
||||||
return koboldWorldUid;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createTavernEntries(tavernEntriesToCreate, koboldWorldUid, tavernWorldInfo) {
|
|
||||||
if (tavernEntriesToCreate.length && koboldWorldUid) {
|
|
||||||
for (const tavernUid of tavernEntriesToCreate) {
|
|
||||||
try {
|
|
||||||
const tavernEntry = tavernWorldInfo.entries[tavernUid];
|
|
||||||
const koboldEntry = await postAsync(`${api_server}/v1/world_info/folders/${koboldWorldUid}`, { data: {}, ...baseRequestArgs });
|
|
||||||
await setKoboldEntryData(tavernEntry, koboldEntry);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Couldn't create Kobold world info entry, tavernUid=${tavernUid}. Skipping...`);
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteKoboldEntries(koboldEntriesToDelete) {
|
|
||||||
if (koboldEntriesToDelete.length) {
|
|
||||||
for (const uid of koboldEntriesToDelete) {
|
|
||||||
try {
|
|
||||||
await deleteAsync(`${api_server}/v1/world_info/${uid}`);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Couldn't delete Kobold world info entry, uid=${uid}. Skipping...`);
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteKoboldFolders(koboldFoldersToDelete) {
|
|
||||||
if (koboldFoldersToDelete.length) {
|
|
||||||
for (const uid of koboldFoldersToDelete) {
|
|
||||||
try {
|
|
||||||
await deleteAsync(api_server + `/v1/world_info/folders/${uid}`, baseRequestArgs);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Couldn't delete Kobold world info folder, uid=${uid}. Skipping...`);
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setKoboldEntryData(tavernEntry, koboldEntry) {
|
|
||||||
// 1. Set primary key
|
|
||||||
if (tavernEntry.key?.length) {
|
|
||||||
const keyArgs = { data: { value: tavernEntry.key.join(',') }, ...baseRequestArgs };
|
|
||||||
await putAsync(`${api_server}/v1/world_info/${koboldEntry.uid}/key`, keyArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Set secondary key
|
|
||||||
if (tavernEntry.keysecondary?.length) {
|
|
||||||
const keySecondaryArgs = { data: { value: tavernEntry.keysecondary.join(',') }, ...baseRequestArgs };
|
|
||||||
await putAsync(`${api_server}/v1/world_info/${koboldEntry.uid}/keysecondary`, keySecondaryArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Set content
|
|
||||||
if (tavernEntry.content) {
|
|
||||||
const contentArgs = { data: { value: tavernEntry.content }, ...baseRequestArgs };
|
|
||||||
await putAsync(`${api_server}/v1/world_info/${koboldEntry.uid}/content`, contentArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Set comment
|
|
||||||
if (tavernEntry.comment) {
|
|
||||||
const commentArgs = { data: { value: tavernEntry.comment }, ...baseRequestArgs };
|
|
||||||
await putAsync(`${api_server}/v1/world_info/${koboldEntry.uid}/comment`, commentArgs);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Fixed in Kobold United only: https://github.com/henk717/KoboldAI/pull/280 */
|
|
||||||
try {
|
|
||||||
// 5. Set constant flag
|
|
||||||
if (tavernEntry.constant) {
|
|
||||||
const constantArgs = { data: { value: tavernEntry.constant.toString() }, ...baseRequestArgs };
|
|
||||||
await putToPromise(`${api_server}/v1/world_info/${koboldEntry.uid}/constant`, constantArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. Set selective flag
|
|
||||||
if (tavernEntry.selective) {
|
|
||||||
const selectiveArgs = { data: { value: tavernEntry.selective.toString() }, ...baseRequestArgs };
|
|
||||||
await putToPromise(`${api_server}/v1/world_info/${koboldEntry.uid}/selective`, selectiveArgs);
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// couldn't set fields = ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function validateKoboldWorldInfo(koboldFolderName, koboldWorldInfo, tavernWorldInfo) {
|
|
||||||
let shouldCreateWorld = true;
|
|
||||||
let koboldWorldUid = null;
|
|
||||||
|
|
||||||
const koboldEntriesToDelete = []; // KoboldUIDs
|
|
||||||
const koboldFoldersToDelete = []; // KoboldUIDs
|
|
||||||
const tavernEntriesToCreate = []; // TavernUIDs
|
|
||||||
|
|
||||||
if (koboldWorldInfo?.folders?.length) {
|
|
||||||
let existingFolderAlreadyFound = false;
|
|
||||||
|
|
||||||
for (const folder of koboldWorldInfo.folders) {
|
|
||||||
// Don't care about non-Tavern folders
|
|
||||||
if (!isTavernKoboldWorldInfo(folder.name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other Tavern folders should be deleted (including dupes). If folder name selected is null, then delete anyway to clean-up
|
|
||||||
if (!koboldFolderName || folder.name !== koboldFolderName || existingFolderAlreadyFound) {
|
|
||||||
koboldFoldersToDelete.push(folder.uid);
|
|
||||||
// Should also delete all entries in folder otherwise they will be detached
|
|
||||||
if (Array.isArray(folder.entries)) {
|
|
||||||
koboldEntriesToDelete.push(...folder.entries.map(entry => entry.uid));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate existing entries in Kobold world
|
|
||||||
if (folder.name === koboldFolderName) {
|
|
||||||
existingFolderAlreadyFound = true;
|
|
||||||
shouldCreateWorld = false;
|
|
||||||
koboldWorldUid = folder.uid;
|
|
||||||
if (folder.entries?.length) {
|
|
||||||
const foundTavernEntries = [];
|
|
||||||
for (const koboldEntry of folder.entries) {
|
|
||||||
const tavernEntry = findTavernWorldEntry(tavernWorldInfo, koboldEntry.key, koboldEntry.content);
|
|
||||||
|
|
||||||
if (tavernEntry) {
|
|
||||||
foundTavernEntries.push(tavernEntry.uid);
|
|
||||||
if (isEntryOutOfSync(tavernEntry, koboldEntry)) {
|
|
||||||
// Entry is out of sync. Should be recreated
|
|
||||||
koboldEntriesToDelete.push(koboldEntry.uid);
|
|
||||||
tavernEntriesToCreate.push(tavernEntry.uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// We don't have that entry in our world. It should be deleted
|
|
||||||
koboldEntriesToDelete.push(koboldEntry.uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if every tavern entry was found in kobold world
|
|
||||||
// BTW. Entries is an object, not an array!
|
|
||||||
for (const tavernEntryUid in tavernWorldInfo.entries) {
|
|
||||||
const tavernEntry = tavernWorldInfo.entries[tavernEntryUid];
|
|
||||||
if (!foundTavernEntries.includes(tavernEntry.uid)) {
|
|
||||||
tavernEntriesToCreate.push(tavernEntry.uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { shouldCreateWorld, koboldWorldUid, tavernEntriesToCreate, koboldEntriesToDelete, koboldFoldersToDelete };
|
|
||||||
}
|
|
||||||
|
|
||||||
function isEntryOutOfSync(tavernEntry, koboldEntry) {
|
|
||||||
return tavernEntry.content !== koboldEntry.content ||
|
|
||||||
tavernEntry.comment !== koboldEntry.comment ||
|
|
||||||
tavernEntry.selective !== koboldEntry.selective ||
|
|
||||||
tavernEntry.constant !== koboldEntry.constant ||
|
|
||||||
tavernEntry.key.join(',') !== koboldEntry.key ||
|
|
||||||
(koboldEntry.selective ? tavernEntry.keysecondary.join(',') !== koboldEntry.keysecondary : false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ** REST CLIENT ASYNC WRAPPERS **
|
// ** REST CLIENT ASYNC WRAPPERS **
|
||||||
function deleteAsync(url, args) {
|
function deleteAsync(url, args) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -1560,15 +1324,6 @@ function getAsync(url, args) {
|
|||||||
}
|
}
|
||||||
// ** END **
|
// ** END **
|
||||||
|
|
||||||
function getKoboldWorldInfoName(worldInfoName) {
|
|
||||||
return worldInfoName ? `TavernAI_${worldInfoName}_WI` : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isTavernKoboldWorldInfo(folderName) {
|
|
||||||
return /^TavernAI_(.*)_WI$/.test(folderName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
app.listen(server_port, function() {
|
app.listen(server_port, function() {
|
||||||
if(process.env.colab !== undefined){
|
if(process.env.colab !== undefined){
|
||||||
if(process.env.colab == 2){
|
if(process.env.colab == 2){
|
||||||
|
Reference in New Issue
Block a user