mirror of
https://github.com/KoboldAI/KoboldAI-Client.git
synced 2025-06-05 21:59:24 +02:00
Added save overwrite, download as json, and fixed some css properties
This commit is contained in:
32
aiserver.py
32
aiserver.py
@@ -6306,8 +6306,38 @@ def UI_2_var_change(data):
|
|||||||
#==================================================================#
|
#==================================================================#
|
||||||
@socketio.on('save_story')
|
@socketio.on('save_story')
|
||||||
def UI_2_save_story(data):
|
def UI_2_save_story(data):
|
||||||
koboldai_vars.save_story()
|
|
||||||
|
|
||||||
|
if data is None:
|
||||||
|
#We need to check to see if there is a file already and if it's not the same story so we can ask the client if this is OK
|
||||||
|
save_name = koboldai_vars.story_name if koboldai_vars.story_name != "" else "untitled"
|
||||||
|
same_story = True
|
||||||
|
if os.path.exists("stories/{}_v2.json".format(save_name)):
|
||||||
|
with open("stories/{}_v2.json".format(save_name), "r") as settings_file:
|
||||||
|
json_data = json.load(settings_file)
|
||||||
|
if 'story_id' in json_data:
|
||||||
|
same_story = json_data['story_id'] == koboldai_vars.story_id
|
||||||
|
else:
|
||||||
|
same_story = False
|
||||||
|
|
||||||
|
if same_story:
|
||||||
|
koboldai_vars.save_story()
|
||||||
|
return "OK"
|
||||||
|
else:
|
||||||
|
return "overwrite?"
|
||||||
|
else:
|
||||||
|
#We have an ack that it's OK to save over the file if one exists
|
||||||
|
koboldai_vars.save_story()
|
||||||
|
|
||||||
|
#==================================================================#
|
||||||
|
# Save story to json
|
||||||
|
#==================================================================#
|
||||||
|
@app.route("/json")
|
||||||
|
def UI_2_save_to_json():
|
||||||
|
return Response(
|
||||||
|
koboldai_vars.to_json('story_settings'),
|
||||||
|
mimetype="application/json",
|
||||||
|
headers={"Content-disposition":
|
||||||
|
"attachment; filename={}_v2.json".format(koboldai_vars.story_name)})
|
||||||
|
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
|
@@ -365,7 +365,7 @@ class story_settings(settings):
|
|||||||
|
|
||||||
def save_story(self):
|
def save_story(self):
|
||||||
print("Saving")
|
print("Saving")
|
||||||
save_name = self.story_name if self.story_name is not "" else "untitled"
|
save_name = self.story_name if self.story_name != "" else "untitled"
|
||||||
with open("stories/{}_v2.json".format(save_name), "w") as settings_file:
|
with open("stories/{}_v2.json".format(save_name), "w") as settings_file:
|
||||||
settings_file.write(self.to_json())
|
settings_file.write(self.to_json())
|
||||||
self.gamesaved = True
|
self.gamesaved = True
|
||||||
@@ -387,8 +387,16 @@ class story_settings(settings):
|
|||||||
if name == "gamesaved" and value == False and self.autosave:
|
if name == "gamesaved" and value == False and self.autosave:
|
||||||
self.save_story()
|
self.save_story()
|
||||||
if not new_variable and old_value != value:
|
if not new_variable and old_value != value:
|
||||||
|
#Change game save state
|
||||||
|
if name in ['story_name', 'prompt', 'memory', 'authornote', 'authornotetemplate', 'andepth', 'chatname', 'actionmode', 'dynamicscan', 'notes', 'biases']:
|
||||||
|
self.gamesaved = False
|
||||||
|
|
||||||
if name == 'actions':
|
if name == 'actions':
|
||||||
self.actions.story_settings = self
|
self.actions.story_settings = self
|
||||||
|
elif name == 'story_name':
|
||||||
|
#reset the story id if we change the name
|
||||||
|
self.story_id = int.from_bytes(os.urandom(16), 'little', signed=True)
|
||||||
|
|
||||||
#Recalc token length
|
#Recalc token length
|
||||||
elif name in ['authornote', 'memory' ,'prompt', 'tokenizer'] and self.tokenizer is not None:
|
elif name in ['authornote', 'memory' ,'prompt', 'tokenizer'] and self.tokenizer is not None:
|
||||||
if name == 'tokenizer' and not new_variable:
|
if name == 'tokenizer' and not new_variable:
|
||||||
|
@@ -466,6 +466,7 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
background-color: var(--flyout_background);
|
background-color: var(--flyout_background);
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
overflow-y: hidden;
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
padding-top: 20px;
|
padding-top: 20px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
@@ -883,6 +884,7 @@ body {
|
|||||||
|
|
||||||
.popup .popup_load_cancel {
|
.popup .popup_load_cancel {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
vertical-align: bottom;
|
||||||
background-color: var(--popup_title_bar_color);
|
background-color: var(--popup_title_bar_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1082,3 +1084,13 @@ textarea {
|
|||||||
body.NotConnected {
|
body.NotConnected {
|
||||||
filter: grayscale(80%);
|
filter: grayscale(80%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cursor {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flout_menu_contents {
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
height: 80vh;
|
||||||
|
}
|
@@ -1249,8 +1249,10 @@ function world_info_folder(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------UI to Server Functions----------------------------------
|
//--------------------------------------------UI to Server Functions----------------------------------
|
||||||
function save_as_story() {
|
function save_as_story(response) {
|
||||||
|
if (response == "overwrite?") {
|
||||||
|
document.getElementById('save-confirm').classList.remove('hidden')
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1750,14 +1752,22 @@ function assign_world_info_to_action(uid=null, action_item=null) {
|
|||||||
function update_token_lengths() {
|
function update_token_lengths() {
|
||||||
max_token_length = parseInt(document.getElementById("model_max_length_cur").value);
|
max_token_length = parseInt(document.getElementById("model_max_length_cur").value);
|
||||||
included_world_info = [];
|
included_world_info = [];
|
||||||
|
//clear out the world info included tags
|
||||||
for (item of document.getElementsByClassName("world_info_included")) {
|
for (item of document.getElementsByClassName("world_info_included")) {
|
||||||
item.classList.remove("world_info_included");
|
item.classList.remove("world_info_included");
|
||||||
}
|
}
|
||||||
|
//clear out the text tags
|
||||||
|
for (item of document.getElementsByClassName("within_max_length")) {
|
||||||
|
item.classList.remove("within_max_length");
|
||||||
|
}
|
||||||
|
|
||||||
|
//figure out memory length
|
||||||
if ((document.getElementById("memory").getAttribute("story_memory_length") == null) || (document.getElementById("memory").getAttribute("story_memory_length") == "")) {
|
if ((document.getElementById("memory").getAttribute("story_memory_length") == null) || (document.getElementById("memory").getAttribute("story_memory_length") == "")) {
|
||||||
memory_length = 0;
|
memory_length = 0;
|
||||||
} else {
|
} else {
|
||||||
memory_length = parseInt(document.getElementById("memory").getAttribute("story_memory_length"));
|
memory_length = parseInt(document.getElementById("memory").getAttribute("story_memory_length"));
|
||||||
}
|
}
|
||||||
|
//figure out and tag the length of all the constant world infos
|
||||||
for (uid in world_info_data) {
|
for (uid in world_info_data) {
|
||||||
if (world_info_data[uid].constant) {
|
if (world_info_data[uid].constant) {
|
||||||
if (world_info_data[uid].token_length != null) {
|
if (world_info_data[uid].token_length != null) {
|
||||||
@@ -1767,19 +1777,23 @@ function update_token_lengths() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Figure out author's notes length
|
||||||
if ((document.getElementById("authors_notes").getAttribute("story_authornote_length") == null) || (document.getElementById("authors_notes").getAttribute("story_authornote_length") == "")) {
|
if ((document.getElementById("authors_notes").getAttribute("story_authornote_length") == null) || (document.getElementById("authors_notes").getAttribute("story_authornote_length") == "")) {
|
||||||
authors_notes = 0;
|
authors_notes = 0;
|
||||||
} else {
|
} else {
|
||||||
authors_notes = parseInt(document.getElementById("authors_notes").getAttribute("story_authornote_length"));
|
authors_notes = parseInt(document.getElementById("authors_notes").getAttribute("story_authornote_length"));
|
||||||
}
|
}
|
||||||
|
//figure out prompt length
|
||||||
if ((document.getElementById("story_prompt").getAttribute("story_prompt_length") == null) || (document.getElementById("story_prompt").getAttribute("story_prompt_length") == "")) {
|
if ((document.getElementById("story_prompt").getAttribute("story_prompt_length") == null) || (document.getElementById("story_prompt").getAttribute("story_prompt_length") == "")) {
|
||||||
prompt_length = 999999999999;
|
prompt_length = 999999999999;
|
||||||
} else {
|
} else {
|
||||||
prompt_length = parseInt(document.getElementById("story_prompt").getAttribute("story_prompt_length"));
|
prompt_length = parseInt(document.getElementById("story_prompt").getAttribute("story_prompt_length"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//used token length
|
||||||
token_length = memory_length + authors_notes;
|
token_length = memory_length + authors_notes;
|
||||||
|
|
||||||
|
//add in the prompt length if it's set to always add, otherwise add it later
|
||||||
always_prompt = document.getElementById("story_useprompt").value == "true";
|
always_prompt = document.getElementById("story_useprompt").value == "true";
|
||||||
if (always_prompt) {
|
if (always_prompt) {
|
||||||
token_length += prompt_length
|
token_length += prompt_length
|
||||||
@@ -1795,6 +1809,7 @@ function update_token_lengths() {
|
|||||||
} else {
|
} else {
|
||||||
document.getElementById("story_prompt").classList.remove("within_max_length");
|
document.getElementById("story_prompt").classList.remove("within_max_length");
|
||||||
}
|
}
|
||||||
|
//figure out how many chunks we have
|
||||||
max_chunk = -1;
|
max_chunk = -1;
|
||||||
for (item of document.getElementById("Selected Text").childNodes) {
|
for (item of document.getElementById("Selected Text").childNodes) {
|
||||||
if (item.id != undefined) {
|
if (item.id != undefined) {
|
||||||
@@ -1807,13 +1822,14 @@ function update_token_lengths() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go backwards through the text chunks and tag them if we still have space
|
||||||
for (var chunk=max_chunk;chunk >= 0;chunk--) {
|
for (var chunk=max_chunk;chunk >= 0;chunk--) {
|
||||||
if (document.getElementById("Selected Text Chunk "+chunk).getAttribute("token_length") == null) {
|
if (document.getElementById("Selected Text Chunk "+chunk).getAttribute("token_length") == null) {
|
||||||
current_chunk_length = 999999999999;
|
current_chunk_length = 999999999999;
|
||||||
} else {
|
} else {
|
||||||
current_chunk_length = parseInt(document.getElementById("Selected Text Chunk "+chunk).getAttribute("token_length"));
|
current_chunk_length = parseInt(document.getElementById("Selected Text Chunk "+chunk).getAttribute("token_length"));
|
||||||
}
|
}
|
||||||
if (token_length+current_chunk_length < max_token_length) {
|
if ((current_chunk_length != 0) && (token_length+current_chunk_length < max_token_length)) {
|
||||||
token_length += current_chunk_length;
|
token_length += current_chunk_length;
|
||||||
document.getElementById("Selected Text Chunk "+chunk).classList.add("within_max_length");
|
document.getElementById("Selected Text Chunk "+chunk).classList.add("within_max_length");
|
||||||
uids = document.getElementById("Selected Text Chunk "+chunk).getAttribute("world_info_uids")
|
uids = document.getElementById("Selected Text Chunk "+chunk).getAttribute("world_info_uids")
|
||||||
@@ -1829,6 +1845,7 @@ function update_token_lengths() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if we don't always add prompts
|
||||||
if ((!always_prompt) && (token_length+prompt_length < max_token_length)) {
|
if ((!always_prompt) && (token_length+prompt_length < max_token_length)) {
|
||||||
token_length += prompt_length
|
token_length += prompt_length
|
||||||
document.getElementById("story_prompt").classList.add("within_max_length");
|
document.getElementById("story_prompt").classList.add("within_max_length");
|
||||||
@@ -1843,6 +1860,7 @@ function update_token_lengths() {
|
|||||||
} else if (!always_prompt) {
|
} else if (!always_prompt) {
|
||||||
document.getElementById("story_prompt").classList.remove("within_max_length");
|
document.getElementById("story_prompt").classList.remove("within_max_length");
|
||||||
}
|
}
|
||||||
|
//Add token count to used_token_length tags
|
||||||
for (item of document.getElementsByClassName("used_token_length")) {
|
for (item of document.getElementsByClassName("used_token_length")) {
|
||||||
item.textContent = "Used Tokens: " + token_length;
|
item.textContent = "Used Tokens: " + token_length;
|
||||||
}
|
}
|
||||||
|
@@ -129,5 +129,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<iframe id="download_iframe" style="display:none;"></iframe>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -66,4 +66,18 @@
|
|||||||
<button type="button" class="btn btn-primary" id="btn_loadaccept">Load</button>
|
<button type="button" class="btn btn-primary" id="btn_loadaccept">Load</button>
|
||||||
<button type="button" class="btn btn-primary" id="btn_loadclose">Cancel</button>
|
<button type="button" class="btn btn-primary" id="btn_loadclose">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!---------------- Story overwrite screen ---------------------->
|
||||||
|
<div class="popup hidden" id="save-confirm">
|
||||||
|
<div class="title">
|
||||||
|
<div class="popuptitletext">Overwrite</div>
|
||||||
|
</div>
|
||||||
|
<div id="popup_list_area">
|
||||||
|
The story name you have entered already exists. Would you like to overwrite?
|
||||||
|
</div>
|
||||||
|
<div class="popup_load_cancel">
|
||||||
|
<button type="button" class="btn btn-primary" onclick='socket.emit("save_story", "overwrite"); document.getElementById("save-confirm").classList.add("hidden");'>Overwrite</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="document.getElementById('save-confirm').classList.add('hidden');">Cancel</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@@ -49,10 +49,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="setting_menu_story" class="hidden settings_category_area">
|
<div id="setting_menu_story" class="hidden settings_category_area">
|
||||||
<div id="Story_Info">
|
<div id="Story_Info">
|
||||||
<div>Story Name: <span class="var_sync_story_story_name"></span></div>
|
<div><b>Story Name: </b><span class="var_sync_story_story_name" contenteditable=true onblur="sync_to_server(this);"></span></div>
|
||||||
<div>
|
<div>
|
||||||
<button id="load_story" class="btn action_button" onclick="socket.emit('load_story_list', '');">Load Story</button>
|
<button id="load_story" class="btn action_button" onclick="socket.emit('load_story_list', '');">Load Story</button>
|
||||||
<button id="save_story" class="btn action_button var_sync_alt_story_gamesaved" onclick='socket.emit("save_story", "");'>Save Story</button>
|
<button id="save_story" class="btn action_button var_sync_alt_story_gamesaved" onclick='socket.emit("save_story", null, (response) => {save_as_story(response);});'>Save Story</button>
|
||||||
|
<!---<button id="download_story" class="btn action_button" onclick="document.getElementById('download_iframe').src = 'json';">Download Story</button>--->
|
||||||
|
<a class='cursor' onclick="document.getElementById('download_iframe').src = 'json';">Download Story</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting_tile_area">
|
<div class="setting_tile_area">
|
||||||
|
@@ -26,35 +26,36 @@
|
|||||||
<span class="story_menu_button" onclick="show_story_menu(this, 'story_menu_notes');">Notes</span>
|
<span class="story_menu_button" onclick="show_story_menu(this, 'story_menu_notes');">Notes</span>
|
||||||
<span class="story_menu_button" onclick="show_story_menu(this, 'story_menu_wi');">World Info</span>
|
<span class="story_menu_button" onclick="show_story_menu(this, 'story_menu_wi');">World Info</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flout_menu_contents">
|
||||||
<div id="story_menu_memory" class="story_category_area">
|
<div id="story_menu_memory" class="story_category_area">
|
||||||
<div id="Memory">
|
<div id="Memory">
|
||||||
Memory:<br/>
|
Memory:<br/>
|
||||||
<textarea rows=20 id="memory" class="var_sync_story_memory var_sync_alt_story_memory_length fullwidth" onchange='sync_to_server(this);'></textarea>
|
<textarea rows=20 id="memory" class="var_sync_story_memory var_sync_alt_story_memory_length fullwidth" onchange='sync_to_server(this);'></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div id="story_menu_author" class="story_category_area hidden">
|
||||||
<div id="story_menu_author" class="story_category_area hidden">
|
<div id="author_notes">
|
||||||
<div id="author_notes">
|
Author's Notes:<br/>
|
||||||
Author's Notes:<br/>
|
<textarea rows=5 id="authors_notes" class="var_sync_story_authornote var_sync_alt_story_authornote_length fullwidth" onchange='sync_to_server(this);'></textarea><br/>
|
||||||
<textarea rows=5 id="authors_notes" class="var_sync_story_authornote var_sync_alt_story_authornote_length fullwidth" onchange='sync_to_server(this);'></textarea><br/>
|
Template:<br/>
|
||||||
Template:<br/>
|
<input type=text class="var_sync_story_authornotetemplate fullwidth" onchange='sync_to_server(this);'><br/>
|
||||||
<input type=text class="var_sync_story_authornotetemplate fullwidth" onchange='sync_to_server(this);'><br/>
|
andepth<br/>
|
||||||
andepth<br/>
|
<input type="range" min="0" max="5" step="1"
|
||||||
<input type="range" min="0" max="5" step="1"
|
value="3" class="setting_item_input var_sync_story_andepth"
|
||||||
value="3" class="setting_item_input var_sync_story_andepth"
|
onchange='sync_to_server(this);'>
|
||||||
onchange='sync_to_server(this);'>
|
<span style='display: grid; grid-template-areas: "minlabel maxlabel"'>
|
||||||
<span style='display: grid; grid-template-areas: "minlabel maxlabel"'>
|
<span class=setting_minlabel>0</span>
|
||||||
<span class=setting_minlabel>0</span>
|
<span class=setting_maxlabel>5</span>
|
||||||
<span class=setting_maxlabel>5</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div id="story_menu_notes" class="story_category_area hidden">
|
||||||
<div id="story_menu_notes" class="story_category_area hidden">
|
<div id="Notes">
|
||||||
<div id="Notes">
|
Notes (ignored by AI):<br/>
|
||||||
Notes (ignored by AI):<br/>
|
<textarea rows=20 class="var_sync_story_notes fullwidth" onchange='sync_to_server(this);'></textarea>
|
||||||
<textarea rows=20 class="var_sync_story_notes fullwidth" onchange='sync_to_server(this);'></textarea>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div id="story_menu_wi" class="story_category_area hidden">
|
||||||
<div id="story_menu_wi" class="story_category_area hidden">
|
<span id="world_info_folder_root" class="WI_Folder"><h2>root</h2></span>
|
||||||
<span id="world_info_folder_root" class="WI_Folder"><h2>root</h2></span>
|
</div>
|
||||||
</div>
|
</div>
|
Reference in New Issue
Block a user