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:
30
aiserver.py
30
aiserver.py
@@ -6306,8 +6306,38 @@ def UI_2_var_change(data):
|
||||
#==================================================================#
|
||||
@socketio.on('save_story')
|
||||
def UI_2_save_story(data):
|
||||
|
||||
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):
|
||||
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:
|
||||
settings_file.write(self.to_json())
|
||||
self.gamesaved = True
|
||||
@@ -387,8 +387,16 @@ class story_settings(settings):
|
||||
if name == "gamesaved" and value == False and self.autosave:
|
||||
self.save_story()
|
||||
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':
|
||||
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
|
||||
elif name in ['authornote', 'memory' ,'prompt', 'tokenizer'] and self.tokenizer is not None:
|
||||
if name == 'tokenizer' and not new_variable:
|
||||
|
@@ -466,6 +466,7 @@
|
||||
right: 0;
|
||||
background-color: var(--flyout_background);
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
transition: 0.5s;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 10px;
|
||||
@@ -883,6 +884,7 @@ body {
|
||||
|
||||
.popup .popup_load_cancel {
|
||||
text-align: center;
|
||||
vertical-align: bottom;
|
||||
background-color: var(--popup_title_bar_color);
|
||||
}
|
||||
|
||||
@@ -1082,3 +1084,13 @@ textarea {
|
||||
body.NotConnected {
|
||||
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----------------------------------
|
||||
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() {
|
||||
max_token_length = parseInt(document.getElementById("model_max_length_cur").value);
|
||||
included_world_info = [];
|
||||
//clear out the world info included tags
|
||||
for (item of document.getElementsByClassName("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") == "")) {
|
||||
memory_length = 0;
|
||||
} else {
|
||||
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) {
|
||||
if (world_info_data[uid].constant) {
|
||||
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") == "")) {
|
||||
authors_notes = 0;
|
||||
} else {
|
||||
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") == "")) {
|
||||
prompt_length = 999999999999;
|
||||
} else {
|
||||
prompt_length = parseInt(document.getElementById("story_prompt").getAttribute("story_prompt_length"));
|
||||
}
|
||||
|
||||
//used token length
|
||||
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";
|
||||
if (always_prompt) {
|
||||
token_length += prompt_length
|
||||
@@ -1795,6 +1809,7 @@ function update_token_lengths() {
|
||||
} else {
|
||||
document.getElementById("story_prompt").classList.remove("within_max_length");
|
||||
}
|
||||
//figure out how many chunks we have
|
||||
max_chunk = -1;
|
||||
for (item of document.getElementById("Selected Text").childNodes) {
|
||||
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--) {
|
||||
if (document.getElementById("Selected Text Chunk "+chunk).getAttribute("token_length") == null) {
|
||||
current_chunk_length = 999999999999;
|
||||
} else {
|
||||
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;
|
||||
document.getElementById("Selected Text Chunk "+chunk).classList.add("within_max_length");
|
||||
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)) {
|
||||
token_length += prompt_length
|
||||
document.getElementById("story_prompt").classList.add("within_max_length");
|
||||
@@ -1843,6 +1860,7 @@ function update_token_lengths() {
|
||||
} else if (!always_prompt) {
|
||||
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")) {
|
||||
item.textContent = "Used Tokens: " + token_length;
|
||||
}
|
||||
|
@@ -129,5 +129,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<iframe id="download_iframe" style="display:none;"></iframe>
|
||||
</body>
|
||||
</html>
|
@@ -67,3 +67,17 @@
|
||||
<button type="button" class="btn btn-primary" id="btn_loadclose">Cancel</button>
|
||||
</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>
|
@@ -49,10 +49,12 @@
|
||||
</div>
|
||||
<div id="setting_menu_story" class="hidden settings_category_area">
|
||||
<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>
|
||||
<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 class="setting_tile_area">
|
||||
|
@@ -26,14 +26,14 @@
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<div id="story_menu_memory" class="story_category_area">
|
||||
<div class="flout_menu_contents">
|
||||
<div id="story_menu_memory" class="story_category_area">
|
||||
<div id="Memory">
|
||||
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>
|
||||
</div>
|
||||
</div>
|
||||
<div id="story_menu_author" class="story_category_area hidden">
|
||||
</div>
|
||||
<div id="story_menu_author" class="story_category_area hidden">
|
||||
<div id="author_notes">
|
||||
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/>
|
||||
@@ -48,13 +48,14 @@
|
||||
<span class=setting_maxlabel>5</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="story_menu_notes" class="story_category_area hidden">
|
||||
</div>
|
||||
<div id="story_menu_notes" class="story_category_area hidden">
|
||||
<div id="Notes">
|
||||
Notes (ignored by AI):<br/>
|
||||
<textarea rows=20 class="var_sync_story_notes fullwidth" onchange='sync_to_server(this);'></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div id="story_menu_wi" class="story_category_area hidden">
|
||||
</div>
|
||||
<div id="story_menu_wi" class="story_category_area hidden">
|
||||
<span id="world_info_folder_root" class="WI_Folder"><h2>root</h2></span>
|
||||
</div>
|
||||
</div>
|
Reference in New Issue
Block a user