From e8c23a9cd50e414236cfdd2dc1d71693f1fac19a Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 9 Feb 2023 12:24:17 +0200 Subject: [PATCH 01/17] Add gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b512c09d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file From 06dc120c2244e8476bbfe168fed1ca70f7be403b Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 9 Feb 2023 12:25:04 +0200 Subject: [PATCH 02/17] Add function template for world info generation --- server.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index b1d1ad1c4..03e97079d 100644 --- a/server.js +++ b/server.js @@ -115,7 +115,7 @@ app.post("/generate", jsonParser, function(request, response_generate = response     //console.log(request.body.prompt); //const dataJson = JSON.parse(request.body); request_promt = request.body.prompt; - + //console.log(request.body); var this_settings = { prompt: request_promt, use_story:false, @@ -133,7 +133,7 @@ app.post("/generate", jsonParser, function(request, response_generate = response use_story:false, use_memory:false, use_authors_note:false, - use_world_info:false, + use_world_info:!!request.body.use_world_info, max_context_length: request.body.max_context_length, max_length: request.body.max_length, rep_pen: request.body.rep_pen, @@ -1026,8 +1026,90 @@ app.post("/importchat", urlencodedParser, function(request, response){ }); +async function generateKoboldWorldInfo(worldInfoName) { + let worldInfoUid = null; + try { + const filename = `${worldInfoName}.json`; + const pathToWorldInfo = path.join('public/worldinfos/', filename); + const koboldFolderName = getKoboldWorldInfoName(worldInfoName); + if (!fs.existsSync(pathToWorldInfo)) { + console.log(`World info file ${filename} doesn't exist. Skipping...`); + return null; + } + const worldInfoText = fs.readFileSync(pathToWorldInfo, 'utf8'); + + const baseArgs = { + headers: { "Content-Type": "application/json" } + }; + + // Check is folder exists + const foldersData = await getToPromise(api_server + "/v1/world_info/folders", baseArgs); + if (foldersData?.folders?.length) { + const existingFolder = foldersData.folders.find(x => x.name === koboldFolderName); + if (existingFolder) { + console.log(`World info folder found: ${existingFolder.uid}`); + worldInfoUid = existingFolder.uid; + } + } + + // Create folder if not already exists + if (!worldInfoUid) { + const createArgs = Object.assign(baseArgs, { data: {} }); + const createdFolder = await postToPromise(api_server + "/v1/world_info/folders", createArgs); + console.log(`World info folder created: ${createdFolder.uid}`); + worldInfoUid = createdFolder.uid; + + // Set a name so we could find the folder later + const setNameArgs = Object.assign(baseArgs, { data: { value: koboldFolderName } }); + await putToPromise(api_server + `/v1/world_info/folders/${worldInfoUid}/name`, setNameArgs); + console.log(`World info folder name set: ${koboldFolderName}`); + } + } catch (err) { + console.error(err); + return null; + } + + return worldInfoUid; +} + +function putToPromise(url, args) { + return new Promise((resolve, reject) => { + client.put(url, args, (data, response) => { + if (response.statusCode >= 400) { + reject(data); + } + resolve(data); + }).on('error', e => reject(e)); + }) +} + +function postToPromise(url, args) { + return new Promise((resolve, reject) => { + client.post(url, args, (data, response) => { + if (response.statusCode >= 400) { + reject(data); + } + resolve(data); + }).on('error', e => reject(e)); + }) +} + +function getToPromise(url, args) { + return new Promise((resolve, reject) => { + client.get(url, args, (data, response) => { + if (response.statusCode >= 400) { + reject(data); + } + resolve(data); + }).on('error', e => reject(e)); + }) +} + +function getKoboldWorldInfoName(worldInfoName) { + return `TavernAI_${worldInfoName}_WI`; +} From c760ba54f2ea9ae097681c51f8ddce7c9b55b522 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 9 Feb 2023 18:38:00 +0200 Subject: [PATCH 03/17] #21 Adds basic support of World Info files loading and synchronization with Kobold API --- public/KoboldAI Worlds/Sample.json | 65 +++++++ public/index.html | 61 ++++++- server.js | 279 ++++++++++++++++++++++++----- 3 files changed, 356 insertions(+), 49 deletions(-) create mode 100644 public/KoboldAI Worlds/Sample.json diff --git a/public/KoboldAI Worlds/Sample.json b/public/KoboldAI Worlds/Sample.json new file mode 100644 index 000000000..7449086cf --- /dev/null +++ b/public/KoboldAI Worlds/Sample.json @@ -0,0 +1,65 @@ +{ + "folders": { + "New Folder": [ + 0, + 1 + ] + }, + "entries": { + "0": { + "uid": 0, + "title": "New World Info Entry", + "key": [ + "Test", + "test" + ], + "keysecondary": [ + "ttest " + ], + "folder": "New Folder", + "constant": false, + "manual_text": "tststststs", + "content": "tststststs", + "comment": "", + "type": "wi", + "token_length": 0, + "selective": true, + "used_in_game": false, + "wpp": { + "name": "", + "type": "", + "format": "W++", + "attributes": {} + }, + "use_wpp": false, + "object_type": null + }, + "1": { + "uid": 1, + "title": "New World Info Entry", + "key": [ + "kkkk" + ], + "keysecondary": [ + "kkkkk" + ], + "folder": "New Folder", + "constant": false, + "manual_text": "gsfgsafgasgsf", + "content": "gsfgsafgasgsf", + "comment": "", + "type": "wi", + "token_length": 0, + "selective": true, + "used_in_game": false, + "wpp": { + "name": "", + "type": "", + "format": "W++", + "attributes": {} + }, + "use_wpp": false, + "object_type": null + } + } +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index e19a7131c..b653f747b 100644 --- a/public/index.html +++ b/public/index.html @@ -102,6 +102,9 @@ var user_avatar = 'you.png'; var temp = 0.5; var amount_gen = 80; + var kobold_world = null; + var koboldai_world_names; + var kobold_world_synced = false; var max_context = 2048;//2048; var rep_pen = 1; var rep_pen_size = 100; @@ -263,6 +266,7 @@ resultCheckStatus(); if(online_status !== 'no_connection'){ var checkStatusNow = setTimeout(getStatus, 3000);//getStatus(); + syncKoboldWorldInfo(false); } }, error: function (jqXHR, exception) { @@ -1927,6 +1931,19 @@ }); + $("#world_info").change(function() { + const selectedWorld = $('#world_info').find(":selected").val(); + kobold_world_synced = false; + kobold_world = null; + + if (selectedWorld !== 'None') { + const worldIndex = Number(selectedWorld); + kobold_world = !isNaN(worldIndex) ? koboldai_world_names[worldIndex] : null; + } + + syncKoboldWorldInfo(true); + }); + $( "#settings_perset" ).change(function() { if($('#settings_perset').find(":selected").val() != 'gui'){ @@ -2005,6 +2022,7 @@ main_api = 'kobold'; $('#max_context_block').css('display', 'block'); $('#amount_gen_block').css('display', 'block'); + $('#world_info').css('display', 'block'); } if($('#main_api').find(":selected").val() == 'novel'){ $('#kobold_api').css("display", "none"); @@ -2012,6 +2030,7 @@ main_api = 'novel'; $('#max_context_block').css('display', 'none'); $('#amount_gen_block').css('display', 'none'); + $('#world_info').css('display', 'none'); } } async function getUserAvatars(){ @@ -2037,7 +2056,35 @@ } } - + async function syncKoboldWorldInfo(force) { + // Don't sync if no world selected + if (!kobold_world || online_status == 'no_connection') { + return; + } + + // Don't sync if synced and not forcing + if (kobold_world_synced && !force) { + return; + } + + const response = await fetch("/synckoboldworld", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ "name": kobold_world }) + }); + + if (response.ok === true) { + const syncData = await response.json(); + + if (syncData.ok) { + kobold_world_synced = true; + } + + if (syncData.busy) { + console.log('Sync API is busy'); + } + } + } $(document).on('input', '#temp', function() { temp = $(this).val(); @@ -2181,6 +2228,11 @@ koboldai_setting_names = {}; koboldai_setting_names = arr_holder; + koboldai_world_names = data.koboldai_world_names; + koboldai_world_names.forEach((item, i) => { + $('#world_info').append(``); + }); + preset_settings = settings.preset_settings; temp = settings.temp; @@ -2321,7 +2373,8 @@ if(type === 'change_name'){ location.reload(); } - + + syncKoboldWorldInfo(false); }, error: function (jqXHR, exception) { console.log(exception); @@ -2946,6 +2999,10 @@

Repetition Penalty Range

select
+

World Info

+ -

World Info

- -
-
+
+

World Info

How to use (?)
+ + +

+Import

+
+
+
+ +
+
+ +
+ + +

World Info creation

+
+
+ + +

File content (read-only)

+ + +
+ + +
+
+
@@ -3141,7 +3273,11 @@
-

World Info

How to use (?)
+

+ World Info +

+Import

+

How to use (?)
+

- World Info + World Info

+Import

-

How to use (?)
+
How to use (?)