mirror of
https://github.com/KoboldAI/KoboldAI-Client.git
synced 2025-06-05 21:59:24 +02:00
Merge branch 'UI2' of https://github.com/ebolam/KoboldAI into UI2
This commit is contained in:
24
aiserver.py
24
aiserver.py
@@ -7341,6 +7341,30 @@ def UI_2_upload_world_info_folder(data):
|
||||
json_data = json.loads(data['data'])
|
||||
koboldai_vars.worldinfo_v2.load_json(json_data, folder=data['folder'])
|
||||
|
||||
@socketio.on('import_world_info')
|
||||
def UI_2_import_world_info(data):
|
||||
wi_data = data["data"]
|
||||
uids = {}
|
||||
|
||||
for folder_name, children in wi_data["folders"].items():
|
||||
koboldai_vars.worldinfo_v2.add_folder(folder_name)
|
||||
for child in children:
|
||||
# Child is index
|
||||
if child not in uids:
|
||||
entry_data = wi_data["entries"][str(child)]
|
||||
uids[child] = koboldai_vars.worldinfo_v2.add_item(
|
||||
title=entry_data["title"],
|
||||
key=entry_data["key"],
|
||||
keysecondary=entry_data["keysecondary"],
|
||||
folder=folder_name,
|
||||
constant=entry_data["constant"],
|
||||
manual_text=entry_data["manual_text"],
|
||||
comment=entry_data["comment"],
|
||||
use_wpp=entry_data["use_wpp"],
|
||||
wpp=entry_data["wpp"],
|
||||
)
|
||||
koboldai_vars.worldinfo_v2.add_item_to_folder(uids[child], folder_name)
|
||||
|
||||
|
||||
#==================================================================#
|
||||
# Event triggered when user edits phrase biases
|
||||
|
@@ -1267,6 +1267,7 @@ class KoboldWorldInfo(object):
|
||||
self.socketio.emit("world_info_folder", {x: self.world_info_folder[x] for x in self.world_info_folder}, broadcast=True, room="UI_2")
|
||||
self.socketio.emit("world_info_entry", self.world_info[uid], broadcast=True, room="UI_2")
|
||||
ignore = self.koboldai_vars.calc_ai_text()
|
||||
return uid
|
||||
|
||||
def edit_item(self, uid, title, key, keysecondary, folder, constant, manual_text, comment, use_wpp=False, before=None, wpp={'name': "", 'type': "", 'format': "W++", 'attributes': {}}):
|
||||
old_folder = self.world_info[uid]['folder']
|
||||
|
@@ -1684,6 +1684,27 @@ body {
|
||||
.context-an {background-color: var(--context_colors_authors_notes);}
|
||||
.context-action {background-color: var(--context_colors_game_text);}
|
||||
|
||||
/* File Drag Indicator */
|
||||
#file-upload-notice {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 99999999;
|
||||
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#file-upload-notice > span {
|
||||
font-size: 50vh;
|
||||
opacity: 0.7;
|
||||
}
|
||||
/*---------------------------------- Global ------------------------------------------------*/
|
||||
.hidden {
|
||||
display: none;
|
||||
|
@@ -2918,6 +2918,89 @@ function detect_key_up(e) {
|
||||
}
|
||||
}
|
||||
|
||||
function loadNAILorebook(data, filename) {
|
||||
let lorebookVersion = data.lorebookVersion;
|
||||
let wi_data = {folders: {[filename]: []}, entries: {}};
|
||||
console.log(`Loading NAI lorebook version ${lorebookVersion}`);
|
||||
|
||||
let i = 0;
|
||||
for (const entry of data.entries) {
|
||||
// contextConfig: Object { suffix: "\n", tokenBudget: 2048, reservedTokens: 0, … }
|
||||
// displayName: "Aboleth"
|
||||
// enabled: true
|
||||
// forceActivation: false
|
||||
// keys: Array [ "Aboleth" ]
|
||||
// lastUpdatedAt: 1624443329051
|
||||
// searchRange: 1000
|
||||
// text
|
||||
|
||||
wi_data.entries[i.toString()] = {
|
||||
"uid": uid,
|
||||
"title": entry.displayName,
|
||||
"key": entry.keys,
|
||||
"keysecondary": [],
|
||||
"folder": folder,
|
||||
"constant": entry.forceActivation,
|
||||
"content": "",
|
||||
"manual_text": entry.text,
|
||||
"comment": "",
|
||||
"token_length": 0,
|
||||
"selective": false,
|
||||
"wpp": {"name": "", "type": "", "format": "W++", "attributes": {}},
|
||||
"use_wpp": false,
|
||||
};
|
||||
wi_data.folders[filename].push(i);
|
||||
|
||||
i++;
|
||||
}
|
||||
socket.emit("import_world_info", {data: wi_data});
|
||||
}
|
||||
|
||||
async function loadKoboldData(data, filename) {
|
||||
if (data.gamestarted !== undefined) {
|
||||
// Story
|
||||
socket.emit("upload_file", {"filename": filename, "data": JSON.stringify(data)});
|
||||
socket.emit("load_story_list", "");
|
||||
} else if (data.folders !== undefined && data.entries !== undefined) {
|
||||
// World Info Folder
|
||||
socket.emit("import_world_info", {data: data});
|
||||
} else {
|
||||
// Bad data
|
||||
console.error("Bad data!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async function processDroppedFile(file) {
|
||||
let extension = /.*\.(.*)/.exec(file.name)[1];
|
||||
console.log("file is", file)
|
||||
let data;
|
||||
|
||||
switch (extension) {
|
||||
case "png":
|
||||
// TODO: Support NovelAI's image lorebook cards. The format for those
|
||||
// is base64-encoded JSON under a TXT key called "naidata".
|
||||
console.warn("TODO: NAI LORECARDS");
|
||||
return;
|
||||
case "json":
|
||||
// KoboldAI file
|
||||
data = JSON.parse(await file.text());
|
||||
loadKoboldData(data, file.name);
|
||||
break;
|
||||
case "lorebook":
|
||||
// NovelAI lorebook, JSON encoded.
|
||||
data = JSON.parse(await file.text());
|
||||
loadNAILorebook(data, file.name);
|
||||
break;
|
||||
case "css":
|
||||
console.warn("TODO: THEME");
|
||||
break;
|
||||
case "lua":
|
||||
console.warn("TODO: USERSCRIPT");
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
create_theming_elements();
|
||||
document.onkeydown = detect_key_down;
|
||||
@@ -2986,4 +3069,41 @@ $(document).ready(function(){
|
||||
$(".token_breakdown").click(function() {
|
||||
document.getElementById("context-viewer-container").classList.remove("hidden");
|
||||
});
|
||||
|
||||
document.body.addEventListener("drop", function(e) {
|
||||
e.preventDefault();
|
||||
$("#file-upload-notice")[0].classList.add("hidden");
|
||||
|
||||
// items api
|
||||
if (e.dataTransfer.items) {
|
||||
for (const item of e.dataTransfer.items) {
|
||||
if (item.kind !== "file") continue;
|
||||
let file = item.getAsFile();
|
||||
processDroppedFile(file);
|
||||
}
|
||||
} else {
|
||||
for (const file of e.dataTransfer.files) {
|
||||
processDroppedFile(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let lastTarget = null;
|
||||
|
||||
document.body.addEventListener("dragover", function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
document.body.addEventListener("dragenter", function(e) {
|
||||
lastTarget = e.target;
|
||||
console.log("start");
|
||||
$("#file-upload-notice")[0].classList.remove("hidden");
|
||||
});
|
||||
|
||||
document.body.addEventListener("dragleave", function(e) {
|
||||
if (!(e.target === document || e.target === lastTarget)) return;
|
||||
|
||||
console.log("end")
|
||||
$("#file-upload-notice")[0].classList.add("hidden");
|
||||
});
|
||||
});
|
||||
|
@@ -139,5 +139,9 @@
|
||||
<div id="context-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="file-upload-notice" class="hidden">
|
||||
<span class="material-icons-outlined">upload_file</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user