mirror of
https://github.com/LostRuins/koboldcpp.git
synced 2025-09-11 01:24:36 +00:00
added support for server side save slots
This commit is contained in:
parent
5ee7cbe08c
commit
ccd2dbe020
3 changed files with 705 additions and 96 deletions
217
kcpp_docs.embd
217
kcpp_docs.embd
|
@ -1491,6 +1491,223 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/extra/data/save": {
|
||||||
|
"post": {
|
||||||
|
"description": "Saves data to a slot in a database file in the KoboldCpp server.",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"slot": "1",
|
||||||
|
"format": "kcpp_lzma_b64",
|
||||||
|
"title": "Untitled Story",
|
||||||
|
"data": "base64_data",
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"slot": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Save slot id to save to."
|
||||||
|
},
|
||||||
|
"format": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Save format, not used currently"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Title of this saved file"
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Save data text string"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"success": true,
|
||||||
|
"error": ""
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"success": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the operation was successful."
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "What went wrong."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Successful request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Saves data to a slot in a database file in the KoboldCpp server.",
|
||||||
|
"tags": [
|
||||||
|
"api/extra/data"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/extra/data/load": {
|
||||||
|
"post": {
|
||||||
|
"description": "Loads data from a save slot in the database file in the KoboldCpp server.",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"slot": "1",
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"slot": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Save slot id"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"success": true,
|
||||||
|
"data": "base64_data"
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"success": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the operation was successful."
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Text string containing the loaded data from server."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Successful request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Loads data from a save slot in the database file in the KoboldCpp server.",
|
||||||
|
"tags": [
|
||||||
|
"api/extra/data"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/extra/data/list": {
|
||||||
|
"post": {
|
||||||
|
"description": "List available saved slots from the KoboldCpp server, returns an array of strings containing their titles.",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": ["Saved Story 1", "Saved Story 2", "", ""],
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Successful request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "List available saved slots from the KoboldCpp server.",
|
||||||
|
"tags": [
|
||||||
|
"api/extra/data"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/admin/list_options": {
|
||||||
|
"get": {
|
||||||
|
"summary": "List available .kcpps files to load.",
|
||||||
|
"description": "List available .kcpps files to load.",
|
||||||
|
"tags": [
|
||||||
|
"api/admin"
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": ["file1.kcpps","file2.kcpps"],
|
||||||
|
"schema": {
|
||||||
|
"properties": {},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Successful request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/admin/reload_config": {
|
||||||
|
"post": {
|
||||||
|
"description": "Switches the loaded config, along with any settings and model file changes.",
|
||||||
|
"requestBody": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"filename": "file1.kcpps",
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"filename": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Filename of the .kcpps config to be loaded. Any associated files and models will be automatically swapped in."
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"example": {
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"properties": {
|
||||||
|
"success": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the operation was successful."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Successful request"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"summary": "Switches the currently loaded .kcpps config, and reloads any changed files or models.",
|
||||||
|
"tags": [
|
||||||
|
"api/admin"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/props": {
|
"/props": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "Returns the Jinja template stored in the GGUF model, if found.",
|
"summary": "Returns the Jinja template stored in the GGUF model, if found.",
|
||||||
|
|
394
klite.embd
394
klite.embd
|
@ -12,7 +12,7 @@ Current version indicated by LITEVER below.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const LITEVER = 217;
|
const LITEVER = 219;
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
var localflag = true;
|
var localflag = true;
|
||||||
const STORAGE_PREFIX = (localflag?"e_":"")+"kaihordewebui_";
|
const STORAGE_PREFIX = (localflag?"e_":"")+"kaihordewebui_";
|
||||||
|
@ -462,13 +462,13 @@ Current version indicated by LITEVER below.
|
||||||
.saveloadpopup {
|
.saveloadpopup {
|
||||||
width: 660px;
|
width: 660px;
|
||||||
background-color: #262626;
|
background-color: #262626;
|
||||||
margin-top: 80px;
|
margin-top: 120px;
|
||||||
}
|
}
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.saveloadpopup {
|
.saveloadpopup {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #262626;
|
background-color: #262626;
|
||||||
margin-top: 80px;
|
margin-top: 120px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.saveloadgrid
|
.saveloadgrid
|
||||||
|
@ -478,7 +478,7 @@ Current version indicated by LITEVER below.
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 4px;
|
gap: 2px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
@media (max-width: 340px) {
|
@media (max-width: 340px) {
|
||||||
|
@ -2212,6 +2212,24 @@ Current version indicated by LITEVER below.
|
||||||
.bg_teal:disabled:hover {
|
.bg_teal:disabled:hover {
|
||||||
background-color: #8a8a8a;
|
background-color: #8a8a8a;
|
||||||
}
|
}
|
||||||
|
.bg_primary {
|
||||||
|
background-color: #337ab7;
|
||||||
|
}
|
||||||
|
.bg_primary:hover {
|
||||||
|
background-color: #286090;
|
||||||
|
}
|
||||||
|
.bg_primary:active:focus {
|
||||||
|
background-color: #23527c;
|
||||||
|
}
|
||||||
|
.bg_primary:focus {
|
||||||
|
background-color: #23527c;
|
||||||
|
}
|
||||||
|
.bg_primary:disabled {
|
||||||
|
background-color: #8a8a8a;
|
||||||
|
}
|
||||||
|
.bg_primary:disabled:hover {
|
||||||
|
background-color: #8a8a8a;
|
||||||
|
}
|
||||||
|
|
||||||
.bluebtn {
|
.bluebtn {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
@ -2832,6 +2850,9 @@ Current version indicated by LITEVER below.
|
||||||
const koboldcpp_tts_endpoint = "/api/extra/tts";
|
const koboldcpp_tts_endpoint = "/api/extra/tts";
|
||||||
const koboldcpp_admin_list_endpoint = "/api/admin/list_options";
|
const koboldcpp_admin_list_endpoint = "/api/admin/list_options";
|
||||||
const koboldcpp_admin_reload_endpoint = "/api/admin/reload_config";
|
const koboldcpp_admin_reload_endpoint = "/api/admin/reload_config";
|
||||||
|
const koboldcpp_savedata_list_endpoint = "/api/extra/data/list";
|
||||||
|
const koboldcpp_savedata_save_endpoint = "/api/extra/data/save";
|
||||||
|
const koboldcpp_savedata_load_endpoint = "/api/extra/data/load";
|
||||||
|
|
||||||
const oai_models_endpoint = "/models";
|
const oai_models_endpoint = "/models";
|
||||||
const oai_submit_endpoint = "/completions";
|
const oai_submit_endpoint = "/completions";
|
||||||
|
@ -2895,7 +2916,7 @@ Current version indicated by LITEVER below.
|
||||||
const HD_RES_PX = 768;
|
const HD_RES_PX = 768;
|
||||||
const NO_HD_RES_PX = 512;
|
const NO_HD_RES_PX = 512;
|
||||||
const AVATAR_PX = 384;
|
const AVATAR_PX = 384;
|
||||||
const SAVE_SLOTS = 6;
|
const SAVE_SLOTS = 8;
|
||||||
const num_regex_rows = 4;
|
const num_regex_rows = 4;
|
||||||
const default_websearch_template = `### New Task:\nFrom above text, rephrase the search engine query "{{QUERY}}" as a single short phrase (for search engines) using proper nouns, references and names to avoid ambiguity.\n\n### Rephrased Search Query Created:\n`;
|
const default_websearch_template = `### New Task:\nFrom above text, rephrase the search engine query "{{QUERY}}" as a single short phrase (for search engines) using proper nouns, references and names to avoid ambiguity.\n\n### Rephrased Search Query Created:\n`;
|
||||||
|
|
||||||
|
@ -2983,6 +3004,7 @@ Current version indicated by LITEVER below.
|
||||||
var koboldcpp_has_vision = false;
|
var koboldcpp_has_vision = false;
|
||||||
var koboldcpp_has_multiplayer = false;
|
var koboldcpp_has_multiplayer = false;
|
||||||
var koboldcpp_has_websearch = false;
|
var koboldcpp_has_websearch = false;
|
||||||
|
var koboldcpp_has_savedatafile = false;
|
||||||
var koboldcpp_admin_type = 0; //0 = no admin, 1=has admin, 2=protected admin
|
var koboldcpp_admin_type = 0; //0 = no admin, 1=has admin, 2=protected admin
|
||||||
var lastSearchQuery = "";
|
var lastSearchQuery = "";
|
||||||
var lastSearchResults = [];
|
var lastSearchResults = [];
|
||||||
|
@ -6066,6 +6088,10 @@ Current version indicated by LITEVER below.
|
||||||
{
|
{
|
||||||
return (custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.78") >= 0 && koboldcpp_has_multiplayer);
|
return (custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.78") >= 0 && koboldcpp_has_multiplayer);
|
||||||
}
|
}
|
||||||
|
function is_using_kcpp_with_savedatafile()
|
||||||
|
{
|
||||||
|
return (custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.84") >= 0 && koboldcpp_has_savedatafile);
|
||||||
|
}
|
||||||
function is_using_kcpp_with_websearch()
|
function is_using_kcpp_with_websearch()
|
||||||
{
|
{
|
||||||
return (custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.80") >= 0 && koboldcpp_has_websearch);
|
return (custom_kobold_endpoint!="" && koboldcpp_version && koboldcpp_version!="" && compare_version_str(koboldcpp_version, "1.80") >= 0 && koboldcpp_has_websearch);
|
||||||
|
@ -9513,6 +9539,7 @@ Current version indicated by LITEVER below.
|
||||||
koboldcpp_has_websearch = (data.websearch?true:false);
|
koboldcpp_has_websearch = (data.websearch?true:false);
|
||||||
koboldcpp_has_tts = (data.tts?true:false);
|
koboldcpp_has_tts = (data.tts?true:false);
|
||||||
koboldcpp_admin_type = (data.admin?data.admin:0);
|
koboldcpp_admin_type = (data.admin?data.admin:0);
|
||||||
|
koboldcpp_has_savedatafile = (data.savedata?true:false)
|
||||||
let has_password = (data.protected?true:false);
|
let has_password = (data.protected?true:false);
|
||||||
let has_txt2img = (data.txt2img?true:false);
|
let has_txt2img = (data.txt2img?true:false);
|
||||||
let no_txt_model = (mdlname=="inactive");
|
let no_txt_model = (mdlname=="inactive");
|
||||||
|
@ -9992,11 +10019,68 @@ Current version indicated by LITEVER below.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cachedsaveslotlabels = [];
|
||||||
|
var netsaveslotlabels = [];
|
||||||
|
function saveloadchangeslot(updatelist=false)
|
||||||
|
{
|
||||||
|
let selectedslot = document.getElementById("saveslotselecteddropdown").value;
|
||||||
|
let selectedlocation = document.getElementById("saveslotlocationdropdown").value;
|
||||||
|
let selectedslotlabel = null;
|
||||||
|
let choices = "";
|
||||||
|
let foundoption = false;
|
||||||
|
if(selectedlocation=="1") //local
|
||||||
|
{
|
||||||
|
for(let i=0;i<cachedsaveslotlabels.length;++i)
|
||||||
|
{
|
||||||
|
let testslot = cachedsaveslotlabels[i];
|
||||||
|
if(selectedslot==i)
|
||||||
|
{
|
||||||
|
selectedslotlabel = testslot;
|
||||||
|
foundoption = true;
|
||||||
|
}
|
||||||
|
let lbl = (i+1);
|
||||||
|
let tsdesc = (testslot.length>50)?testslot.substring(0,50)+"...":testslot;
|
||||||
|
let slotname = (testslot?`Local Slot `+(lbl)+` - `+tsdesc+``:`Local Slot `+(lbl)+` - [ Empty ]`);
|
||||||
|
choices += `<option value=${i}${(selectedslot==i)?" selected":""}>${slotname}</option>`;
|
||||||
|
}
|
||||||
|
} else if(selectedlocation=="2") { //remote saves
|
||||||
|
for(let i=0;i<netsaveslotlabels.length;++i)
|
||||||
|
{
|
||||||
|
let testslot = netsaveslotlabels[i];
|
||||||
|
if(selectedslot==i)
|
||||||
|
{
|
||||||
|
selectedslotlabel = testslot;
|
||||||
|
foundoption = true;
|
||||||
|
}
|
||||||
|
let lbl = (i+1);
|
||||||
|
let tsdesc = (testslot.length>50)?testslot.substring(0,50)+"...":testslot;
|
||||||
|
let slotname = (testslot?`Server Slot `+(lbl)+` - `+tsdesc+``:`Server Slot `+(lbl)+` - [ Empty ]`);
|
||||||
|
choices += `<option value=${i}${(selectedslot==i)?" selected":""}>${slotname}</option>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.getElementById("loadfromslot").disabled = (selectedslotlabel?false:true);
|
||||||
|
document.getElementById("downloadslot").disabled = (selectedslotlabel?false:true);
|
||||||
|
document.getElementById("deleteslot").disabled = (selectedslotlabel?false:true);
|
||||||
|
if(!foundoption)
|
||||||
|
{
|
||||||
|
document.getElementById("saveslotselecteddropdown").selectedIndex = 0;
|
||||||
|
}
|
||||||
|
if(updatelist)
|
||||||
|
{
|
||||||
|
document.getElementById("saveslotselecteddropdown").innerHTML = choices;
|
||||||
|
}
|
||||||
|
}
|
||||||
function display_saveloadcontainer()
|
function display_saveloadcontainer()
|
||||||
{
|
{
|
||||||
mainmenu_untab(true);
|
mainmenu_untab(true);
|
||||||
document.getElementById("saveloadcontainer").classList.remove("hidden");
|
document.getElementById("saveloadcontainer").classList.remove("hidden");
|
||||||
|
|
||||||
|
if (is_using_kcpp_with_savedatafile()) {
|
||||||
|
document.getElementById("kcppsaveavailable").classList.remove("hidden");
|
||||||
|
} else {
|
||||||
|
document.getElementById("kcppsaveavailable").classList.add("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
let slotpromises = [];
|
let slotpromises = [];
|
||||||
for(let i=0;i<SAVE_SLOTS;++i)
|
for(let i=0;i<SAVE_SLOTS;++i)
|
||||||
{
|
{
|
||||||
|
@ -10004,48 +10088,40 @@ Current version indicated by LITEVER below.
|
||||||
}
|
}
|
||||||
Promise.all(slotpromises).then(slotlabels=>
|
Promise.all(slotpromises).then(slotlabels=>
|
||||||
{
|
{
|
||||||
let filetable = ``;
|
cachedsaveslotlabels = slotlabels;
|
||||||
let entry = `<div style="display:flex">
|
saveloadchangeslot(true);
|
||||||
<button type="button" style="font-size:12px; margin:2px;width:33%" name="localsave" class="btn btn-primary" onclick="hide_popups();save_file_button()">`+"💾<br>Download File"+`</button>
|
|
||||||
<button type="button" style="font-size:12px; margin:2px;width:33%" name="localload" class="btn btn-primary" onclick="hide_popups();load_file_button()">`+"📁<br>Open File"+`</button>
|
|
||||||
<button type="button" style="font-size:12px; margin:2px;width:34%" name="shareurl" class="btn btn-primary" onclick="hide_popups();share_story_button()">`+"🌐<br>Share"+`</button>
|
|
||||||
</div>
|
|
||||||
<div style="margin-top:3px; text-align: center; align-self: center; width: calc(100% - 184px);">
|
|
||||||
<span style="font-weight:bold;text-decoration: underline;">Temporary Browser Storage</span>
|
|
||||||
</div>`;
|
|
||||||
filetable += entry;
|
|
||||||
|
|
||||||
for(let i=0;i<slotlabels.length;++i)
|
|
||||||
{
|
|
||||||
let testslot = slotlabels[i];
|
|
||||||
let lbl = (i+1);
|
|
||||||
entry = `<div style="display:flex; height:42px;">
|
|
||||||
<div style="margin:3px; text-align: center; align-self: center; width: calc(100% - 184px);">
|
|
||||||
`+(testslot?`[ Slot `+(lbl)+` - `+testslot+` ]`:`[ Slot `+(lbl)+` - Empty ]`)+`
|
|
||||||
</div>
|
|
||||||
<div style="text-align: right; align-self: center; width: 184px;">
|
|
||||||
<button type="button" title="Save To Slot ${lbl}" class="btn btn-primary" onclick="save_to_slot(${i})"><img class="btnicon-save"/></button>
|
|
||||||
<button type="button" title="Load From Slot ${lbl}" class="btn btn-primary" onclick="load_from_slot(${i})" `+(testslot?"":"disabled")+`><img class="btnicon-load"/></button>
|
|
||||||
<button type="button" title="Download Slot ${lbl}" class="btn btn-primary bg_green" onclick="download_from_slot(${i})" `+(testslot?"":"disabled")+`><img class="btnicon-download"/></button>
|
|
||||||
<button type="button" title="Delete Slot ${lbl}" class="btn btn-primary bg_red" onclick="delete_from_slot(${i})" `+(testslot?"":"disabled")+`><img class="btnicon-delete"/></button>
|
|
||||||
</div></div>`;
|
|
||||||
filetable += entry;
|
|
||||||
}
|
|
||||||
populate_corpo_leftpanel();
|
populate_corpo_leftpanel();
|
||||||
document.getElementById("saveloadentries").innerHTML = filetable;
|
});
|
||||||
|
if(is_using_kcpp_with_savedatafile())
|
||||||
|
{
|
||||||
|
//grab saves
|
||||||
|
fetch(custom_kobold_endpoint + koboldcpp_savedata_list_endpoint, {
|
||||||
|
method: 'POST', // or 'PUT'
|
||||||
|
headers: get_kobold_header(),
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
netsaveslotlabels = data;
|
||||||
|
saveloadchangeslot(true);
|
||||||
|
populate_corpo_leftpanel();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function save_to_slot(slot)
|
}
|
||||||
|
function save_to_slot(slot,islocal)
|
||||||
{
|
{
|
||||||
let defaultsavename = (localsettings.opmode==1?"Untitled Story":(localsettings.opmode==2?"Untitled Adventure":(localsettings.opmode==3?"Untitled Chat":"Untitled Instruct")));
|
let defaultsavename = (localsettings.opmode==1?"Untitled Story":(localsettings.opmode==2?"Untitled Adventure":(localsettings.opmode==3?"Untitled Chat":"Untitled Instruct")));
|
||||||
let savename = defaultsavename + " " + new Date().toLocaleString();
|
let savename = defaultsavename + " " + new Date().toLocaleString();
|
||||||
let slotnumshown = (slot+1);
|
let slotnumshown = (parseInt(slot)+1);
|
||||||
|
let newcompressedstory = generate_compressed_story(true, true, true);
|
||||||
|
if(islocal)
|
||||||
|
{
|
||||||
indexeddb_load("slot_"+slot+"_meta","").then(testslot=>{
|
indexeddb_load("slot_"+slot+"_meta","").then(testslot=>{
|
||||||
if (testslot) {
|
if (testslot) {
|
||||||
savename = testslot;
|
savename = testslot;
|
||||||
}
|
}
|
||||||
let newcompressedstory = generate_compressed_story(true, true, true);
|
|
||||||
|
|
||||||
const slotwrite = function () {
|
const slotwrite = function () {
|
||||||
warn_on_quit = false;
|
warn_on_quit = false;
|
||||||
inputBox("Enter a label for this Browser Storage Slot data", "Enter a label", savename, defaultsavename, () => {
|
inputBox("Enter a label for this Browser Storage Slot data", "Enter a label", savename, defaultsavename, () => {
|
||||||
|
@ -10059,7 +10135,7 @@ Current version indicated by LITEVER below.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testslot) {
|
if (testslot) {
|
||||||
msgboxYesNo("Overwrite existing story in Browser Storage Slot " + slotnumshown + "?", "Overwrite Storage Slot " + slotnumshown, () => {
|
msgboxYesNo("Overwrite existing story in Browser Storage Slot " + slotnumshown + "?", "Overwrite Browser Storage Slot " + slotnumshown, () => {
|
||||||
slotwrite();
|
slotwrite();
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
@ -10067,8 +10143,63 @@ Current version indicated by LITEVER below.
|
||||||
slotwrite();
|
slotwrite();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else { //remote save
|
||||||
|
let testslot = (slot<netsaveslotlabels.length?netsaveslotlabels[slot]:"");
|
||||||
|
if (testslot) {
|
||||||
|
savename = testslot;
|
||||||
}
|
}
|
||||||
function load_from_slot(slot)
|
const slotwrite = function () {
|
||||||
|
warn_on_quit = false;
|
||||||
|
inputBox("Enter a label for this Server Storage Slot data", "Enter a label", savename, defaultsavename, () => {
|
||||||
|
let userinput = getInputBoxValue();
|
||||||
|
if (userinput.trim() == "") {
|
||||||
|
userinput = defaultsavename;
|
||||||
|
}
|
||||||
|
//complete remote save
|
||||||
|
fetch(custom_kobold_endpoint + koboldcpp_savedata_save_endpoint, {
|
||||||
|
method: 'POST', // or 'PUT'
|
||||||
|
headers: get_kobold_header(),
|
||||||
|
body: JSON.stringify({
|
||||||
|
"slot": slot,
|
||||||
|
"format": "kcpp_lzma_b64",
|
||||||
|
"title": userinput,
|
||||||
|
"data": newcompressedstory,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
if(!data.success)
|
||||||
|
{
|
||||||
|
msgbox(`Save Error: ${data.error}`,"Save Failed",false,false,()=>{
|
||||||
|
display_saveloadcontainer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
display_saveloadcontainer();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
msgbox(`Save Error: ${error}`,"Save Failed",false,false,()=>{
|
||||||
|
display_saveloadcontainer();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (testslot) {
|
||||||
|
msgboxYesNo("Overwrite existing story in Server Storage Slot " + slotnumshown + "?", "Overwrite Server Storage Slot " + slotnumshown, () => {
|
||||||
|
slotwrite();
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
slotwrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function load_from_slot(slot,islocal)
|
||||||
|
{
|
||||||
|
if(islocal)
|
||||||
{
|
{
|
||||||
indexeddb_load("slot_"+slot+"_data","").then(loadedstorycompressed=>{
|
indexeddb_load("slot_"+slot+"_data","").then(loadedstorycompressed=>{
|
||||||
if(loadedstorycompressed)
|
if(loadedstorycompressed)
|
||||||
|
@ -10079,36 +10210,155 @@ Current version indicated by LITEVER below.
|
||||||
msgbox("Unable to load story from browser storage","Browser Storage Load Failed");
|
msgbox("Unable to load story from browser storage","Browser Storage Load Failed");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
function download_from_slot(slot)
|
fetch(custom_kobold_endpoint + koboldcpp_savedata_load_endpoint, {
|
||||||
|
method: 'POST', // or 'PUT'
|
||||||
|
headers: get_kobold_header(),
|
||||||
|
body: JSON.stringify({
|
||||||
|
"slot": slot,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((resp) => {
|
||||||
|
if(!resp.success || !resp.data)
|
||||||
{
|
{
|
||||||
indexeddb_load("slot_"+slot+"_data","").then(loadedstorycompressed=>{
|
msgbox("Error: Unable to load story from server storage","Server Storage Load Failed");
|
||||||
if(loadedstorycompressed)
|
|
||||||
{
|
|
||||||
tempfileobj = decompress_story(loadedstorycompressed);
|
|
||||||
if(tempfileobj)
|
|
||||||
{
|
|
||||||
save_file_button(true);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tempfileobj = generate_base_storyobj();
|
hide_popups();
|
||||||
msgbox("Story could not be downloaded. Try loading it first.","Browser Storage Load Failed");
|
import_compressed_story(resp.data.data,false);
|
||||||
}
|
|
||||||
}else{
|
|
||||||
msgbox("Unable to load story from browser storage","Browser Storage Load Failed");
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
msgbox("Error: Unable to load story from server storage","Server Storage Load Failed");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function delete_from_slot(slot)
|
}
|
||||||
|
function download_from_slot(slot,islocal)
|
||||||
{
|
{
|
||||||
let slotnumshown = (slot+1);
|
let ondl = function (loadedstorycompressed) {
|
||||||
msgboxYesNo("Delete story in Browser Storage Slot "+slotnumshown+"?","Delete Storage Slot "+slotnumshown,()=>{
|
if (loadedstorycompressed) {
|
||||||
|
tempfileobj = decompress_story(loadedstorycompressed);
|
||||||
|
if (tempfileobj) {
|
||||||
|
save_file_button(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tempfileobj = generate_base_storyobj();
|
||||||
|
msgbox("Story could not be downloaded. Try loading it first.", "Download Failed");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msgbox("Unable to download story.", "Download Load Failed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(islocal)
|
||||||
|
{
|
||||||
|
indexeddb_load("slot_"+slot+"_data","").then(loadedstorycompressed=>{
|
||||||
|
ondl(loadedstorycompressed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fetch(custom_kobold_endpoint + koboldcpp_savedata_load_endpoint, {
|
||||||
|
method: 'POST', // or 'PUT'
|
||||||
|
headers: get_kobold_header(),
|
||||||
|
body: JSON.stringify({
|
||||||
|
"slot": slot,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((resp) => {
|
||||||
|
if(!resp.success || !resp.data)
|
||||||
|
{
|
||||||
|
msgbox("Error: Unable to load story from server storage","Server Storage Load Failed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ondl(resp.data.data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
msgbox("Error: Unable to load story from server storage","Server Storage Load Failed");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function delete_from_slot(slot,islocal)
|
||||||
|
{
|
||||||
|
let slotnumshown = (parseInt(slot)+1);
|
||||||
|
if (islocal) {
|
||||||
|
msgboxYesNo("Delete story in Browser Storage Slot " + slotnumshown + "?", "Delete Browser Storage Slot " + slotnumshown, () => {
|
||||||
indexeddb_save("slot_" + slot + "_data", "");
|
indexeddb_save("slot_" + slot + "_data", "");
|
||||||
indexeddb_save("slot_" + slot + "_meta", "").then(() => { display_saveloadcontainer() });
|
indexeddb_save("slot_" + slot + "_meta", "").then(() => { display_saveloadcontainer() });
|
||||||
}, () => {
|
}, () => {
|
||||||
display_saveloadcontainer();
|
display_saveloadcontainer();
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
msgboxYesNo("Delete story in Server Storage Slot " + slotnumshown + "?", "Delete Server Storage Slot " + slotnumshown, () => {
|
||||||
|
fetch(custom_kobold_endpoint + koboldcpp_savedata_save_endpoint, {
|
||||||
|
method: 'POST', // or 'PUT'
|
||||||
|
headers: get_kobold_header(),
|
||||||
|
body: JSON.stringify({
|
||||||
|
"slot": slot,
|
||||||
|
"format": "",
|
||||||
|
"title": "",
|
||||||
|
"data": "",
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
if(!data.success)
|
||||||
|
{
|
||||||
|
msgbox(`Delete Error: ${data.error}`,"Delete Failed",false,false,()=>{
|
||||||
|
display_saveloadcontainer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
display_saveloadcontainer();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
msgbox(`Delete Error: ${error}`,"Delete Failed",false,false,()=>{
|
||||||
|
display_saveloadcontainer();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, () => {
|
||||||
|
display_saveloadcontainer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_to_curr_slot()
|
||||||
|
{
|
||||||
|
let selectedslot = document.getElementById("saveslotselecteddropdown").value;
|
||||||
|
let selectedlocation = document.getElementById("saveslotlocationdropdown").value;
|
||||||
|
let islocal = (selectedlocation=="1");
|
||||||
|
save_to_slot(selectedslot,islocal);
|
||||||
|
}
|
||||||
|
function load_from_curr_slot()
|
||||||
|
{
|
||||||
|
let selectedslot = document.getElementById("saveslotselecteddropdown").value;
|
||||||
|
let selectedlocation = document.getElementById("saveslotlocationdropdown").value;
|
||||||
|
let islocal = (selectedlocation=="1");
|
||||||
|
load_from_slot(selectedslot,islocal);
|
||||||
|
}
|
||||||
|
function download_from_curr_slot()
|
||||||
|
{
|
||||||
|
let selectedslot = document.getElementById("saveslotselecteddropdown").value;
|
||||||
|
let selectedlocation = document.getElementById("saveslotlocationdropdown").value;
|
||||||
|
let islocal = (selectedlocation=="1");
|
||||||
|
download_from_slot(selectedslot,islocal);
|
||||||
|
}
|
||||||
|
function delete_from_curr_slot()
|
||||||
|
{
|
||||||
|
let selectedslot = document.getElementById("saveslotselecteddropdown").value;
|
||||||
|
let selectedlocation = document.getElementById("saveslotlocationdropdown").value;
|
||||||
|
let islocal = (selectedlocation=="1");
|
||||||
|
delete_from_slot(selectedslot,islocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cached_model_list = null;
|
var cached_model_list = null;
|
||||||
|
@ -20213,8 +20463,38 @@ Current version indicated by LITEVER below.
|
||||||
|
|
||||||
<div style="overflow: auto;">
|
<div style="overflow: auto;">
|
||||||
<div id="saveloadentries" class="menutext saveloadgrid">
|
<div id="saveloadentries" class="menutext saveloadgrid">
|
||||||
|
<div style="display:flex">
|
||||||
|
<button type="button" style="font-size:12px; margin:2px;width:33%" name="localsave" class="btn btn-primary" onclick="hide_popups();save_file_button()">💾<br>Download File</button>
|
||||||
|
<button type="button" style="font-size:12px; margin:2px;width:33%" name="localload" class="btn btn-primary" onclick="hide_popups();load_file_button()">📁<br>Open File</button>
|
||||||
|
<button type="button" style="font-size:12px; margin:2px;width:34%" name="shareurl" class="btn btn-primary" onclick="hide_popups();share_story_button()">🌐<br>Share</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="menutext"><p style="padding:6px;font-size: 10px;" class="color_red">Caution: Storage Slots are saved to a temporary cache and can be deleted by your browser. To avoid losing data, use the download file button.</p></div>
|
<div style="margin-top:3px; text-align: center; align-self: center; width: 100%">
|
||||||
|
<span style="font-weight:bold;text-decoration: underline;">Slot Storage Option</span>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex;">
|
||||||
|
<div style="width: 92px; margin:8px; margin-left: 4px; margin-right: 4px; font-size: 14px;">Data Location</div>
|
||||||
|
<div style="margin:3px; text-align: center; align-self: center; width: calc(100% - 94px);">
|
||||||
|
<select title="Select Slot Location" style="padding:4px;" class="form-control" id="saveslotlocationdropdown" onchange="saveloadchangeslot(true)">
|
||||||
|
<option value="1">Local Browser Cache</option>
|
||||||
|
<option value="2" id="kcppsaveavailable" class="hidden">KoboldCpp Server Storage</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex;">
|
||||||
|
<div style="width: 92px; margin:8px; margin-left: 4px; margin-right: 4px; font-size: 14px;">Selected Slot</div>
|
||||||
|
<div style="margin:3px; text-align: center; align-self: center; width: calc(100% - 94px);">
|
||||||
|
<select title="Select Save Slot" style="padding:4px;" class="form-control" id="saveslotselecteddropdown" onchange="saveloadchangeslot(false)">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="width:100%;align-self: center;">
|
||||||
|
<button type="button" id="savetoslot" title="Save To Slot" class="btn btn-primary bg_primary" onclick="save_to_curr_slot()"><img class="btnicon-save"/> Save Slot</button>
|
||||||
|
<button type="button" id="loadfromslot" title="Load From Slot" class="btn btn-primary bg_primary" onclick="load_from_curr_slot()"><img class="btnicon-load"/> Load Slot</button>
|
||||||
|
<button type="button" id="downloadslot" title="Download Slot" class="btn btn-primary bg_green" onclick="download_from_curr_slot()"><img class="btnicon-download"/> Download</button>
|
||||||
|
<button type="button" id="deleteslot" title="Delete Slot" class="btn btn-primary bg_red" onclick="delete_from_curr_slot()"><img class="btnicon-delete"/> Delete Slot</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="menutext"><p style="padding:6px;font-size: 10px;" class="color_red">Caution: Local Storage Slots are saved to a temporary cache and can be deleted by your browser. KoboldCpp remote storage will save data to a file in your KoboldCpp server. To avoid losing data, use the download file button.</p></div>
|
||||||
<div class="popupfooter">
|
<div class="popupfooter">
|
||||||
<button type="button" class="btn btn-primary" id=""
|
<button type="button" class="btn btn-primary" id=""
|
||||||
onclick="hide_popups()">Back</button>
|
onclick="hide_popups()">Back</button>
|
||||||
|
|
148
koboldcpp.py
148
koboldcpp.py
|
@ -40,6 +40,7 @@ logprobs_max = 5
|
||||||
default_draft_amount = 8
|
default_draft_amount = 8
|
||||||
default_ttsmaxlen = 4096
|
default_ttsmaxlen = 4096
|
||||||
default_visionmaxres = 1024
|
default_visionmaxres = 1024
|
||||||
|
net_save_slots = 8
|
||||||
|
|
||||||
# abuse prevention
|
# abuse prevention
|
||||||
stop_token_max = 256
|
stop_token_max = 256
|
||||||
|
@ -48,7 +49,7 @@ logit_bias_max = 512
|
||||||
dry_seq_break_max = 128
|
dry_seq_break_max = 128
|
||||||
|
|
||||||
# global vars
|
# global vars
|
||||||
KcppVersion = "1.84.2"
|
KcppVersion = "1.85"
|
||||||
showdebug = True
|
showdebug = True
|
||||||
kcpp_instance = None #global running instance
|
kcpp_instance = None #global running instance
|
||||||
global_memory = {"tunnel_url": "", "restart_target":"", "input_to_exit":False, "load_complete":False}
|
global_memory = {"tunnel_url": "", "restart_target":"", "input_to_exit":False, "load_complete":False}
|
||||||
|
@ -86,6 +87,7 @@ runmode_untouched = True
|
||||||
modelfile_extracted_meta = None
|
modelfile_extracted_meta = None
|
||||||
importvars_in_progress = False
|
importvars_in_progress = False
|
||||||
has_multiplayer = False
|
has_multiplayer = False
|
||||||
|
savedata_obj = None
|
||||||
multiplayer_story_data_compressed = None #stores the full compressed story of the current multiplayer session
|
multiplayer_story_data_compressed = None #stores the full compressed story of the current multiplayer session
|
||||||
multiplayer_turn_major = 1 # to keep track of when a client needs to sync their stories
|
multiplayer_turn_major = 1 # to keep track of when a client needs to sync their stories
|
||||||
multiplayer_turn_minor = 1
|
multiplayer_turn_minor = 1
|
||||||
|
@ -676,7 +678,7 @@ def string_contains_or_overlaps_sequence_substring(inputstr, sequences):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_capabilities():
|
def get_capabilities():
|
||||||
global has_multiplayer, KcppVersion, friendlymodelname, friendlysdmodelname, fullsdmodelpath, mmprojpath, password, fullwhispermodelpath, ttsmodelpath
|
global savedata_obj, has_multiplayer, KcppVersion, friendlymodelname, friendlysdmodelname, fullsdmodelpath, mmprojpath, password, fullwhispermodelpath, ttsmodelpath
|
||||||
has_llm = not (friendlymodelname=="inactive")
|
has_llm = not (friendlymodelname=="inactive")
|
||||||
has_txt2img = not (friendlysdmodelname=="inactive" or fullsdmodelpath=="")
|
has_txt2img = not (friendlysdmodelname=="inactive" or fullsdmodelpath=="")
|
||||||
has_vision = (mmprojpath!="")
|
has_vision = (mmprojpath!="")
|
||||||
|
@ -685,7 +687,7 @@ def get_capabilities():
|
||||||
has_search = True if args.websearch else False
|
has_search = True if args.websearch else False
|
||||||
has_tts = (ttsmodelpath!="")
|
has_tts = (ttsmodelpath!="")
|
||||||
admin_type = (2 if args.admin and args.admindir and args.adminpassword else (1 if args.admin and args.admindir else 0))
|
admin_type = (2 if args.admin and args.admindir and args.adminpassword else (1 if args.admin and args.admindir else 0))
|
||||||
return {"result":"KoboldCpp", "version":KcppVersion, "protected":has_password, "llm":has_llm, "txt2img":has_txt2img,"vision":has_vision,"transcribe":has_whisper,"multiplayer":has_multiplayer,"websearch":has_search,"tts":has_tts, "admin": admin_type}
|
return {"result":"KoboldCpp", "version":KcppVersion, "protected":has_password, "llm":has_llm, "txt2img":has_txt2img,"vision":has_vision,"transcribe":has_whisper,"multiplayer":has_multiplayer,"websearch":has_search,"tts":has_tts, "savedata":(savedata_obj is not None), "admin": admin_type}
|
||||||
|
|
||||||
def dump_gguf_metadata(file_path): #if you're gonna copy this into your own project at least credit concedo
|
def dump_gguf_metadata(file_path): #if you're gonna copy this into your own project at least credit concedo
|
||||||
chunk_size = 1024*1024*12 # read first 12mb of file
|
chunk_size = 1024*1024*12 # read first 12mb of file
|
||||||
|
@ -2362,7 +2364,7 @@ Enter Prompt:<br>
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
global embedded_kailite, embedded_kcpp_docs, embedded_kcpp_sdui
|
global embedded_kailite, embedded_kcpp_docs, embedded_kcpp_sdui
|
||||||
global last_req_time, start_time
|
global last_req_time, start_time
|
||||||
global has_multiplayer, multiplayer_turn_major, multiplayer_turn_minor, multiplayer_story_data_compressed, multiplayer_dataformat, multiplayer_lastactive, maxctx, maxhordelen, friendlymodelname, lastgeneratedcomfyimg, KcppVersion, totalgens, preloaded_story, exitcounter, currentusergenkey, friendlysdmodelname, fullsdmodelpath, mmprojpath, password
|
global savedata_obj, has_multiplayer, multiplayer_turn_major, multiplayer_turn_minor, multiplayer_story_data_compressed, multiplayer_dataformat, multiplayer_lastactive, maxctx, maxhordelen, friendlymodelname, lastgeneratedcomfyimg, KcppVersion, totalgens, preloaded_story, exitcounter, currentusergenkey, friendlysdmodelname, fullsdmodelpath, mmprojpath, password
|
||||||
self.path = self.path.rstrip('/')
|
self.path = self.path.rstrip('/')
|
||||||
response_body = None
|
response_body = None
|
||||||
content_type = 'application/json'
|
content_type = 'application/json'
|
||||||
|
@ -2549,7 +2551,7 @@ Enter Prompt:<br>
|
||||||
return
|
return
|
||||||
|
|
||||||
def do_POST(self):
|
def do_POST(self):
|
||||||
global modelbusy, requestsinqueue, currentusergenkey, totalgens, pendingabortkey, lastgeneratedcomfyimg, multiplayer_turn_major, multiplayer_turn_minor, multiplayer_story_data_compressed, multiplayer_dataformat, multiplayer_lastactive
|
global modelbusy, requestsinqueue, currentusergenkey, totalgens, pendingabortkey, lastgeneratedcomfyimg, multiplayer_turn_major, multiplayer_turn_minor, multiplayer_story_data_compressed, multiplayer_dataformat, multiplayer_lastactive, net_save_slots
|
||||||
contlenstr = self.headers['content-length']
|
contlenstr = self.headers['content-length']
|
||||||
content_length = 0
|
content_length = 0
|
||||||
body = None
|
body = None
|
||||||
|
@ -2707,6 +2709,84 @@ Enter Prompt:<br>
|
||||||
multiplayer_lastactive[sender] = int(time.time())
|
multiplayer_lastactive[sender] = int(time.time())
|
||||||
response_body = (json.dumps({"turn_major":multiplayer_turn_major,"turn_minor":multiplayer_turn_minor,"idle":self.get_multiplayer_idle_state(sender),"data_format":multiplayer_dataformat}).encode())
|
response_body = (json.dumps({"turn_major":multiplayer_turn_major,"turn_minor":multiplayer_turn_minor,"idle":self.get_multiplayer_idle_state(sender),"data_format":multiplayer_dataformat}).encode())
|
||||||
|
|
||||||
|
elif self.path.endswith('/api/extra/data/list'):
|
||||||
|
if not self.secure_endpoint():
|
||||||
|
return
|
||||||
|
if savedata_obj is None:
|
||||||
|
response_body = (json.dumps([]).encode())
|
||||||
|
return
|
||||||
|
output = []
|
||||||
|
for i in range (net_save_slots):
|
||||||
|
if str(i) in savedata_obj:
|
||||||
|
output.append(savedata_obj[str(i)]["title"])
|
||||||
|
else:
|
||||||
|
output.append("")
|
||||||
|
response_body = (json.dumps(output).encode())
|
||||||
|
|
||||||
|
elif self.path.endswith('/api/extra/data/load'):
|
||||||
|
if not self.secure_endpoint():
|
||||||
|
return
|
||||||
|
if savedata_obj is None:
|
||||||
|
response_body = (json.dumps({"success":False,"data":None}).encode())
|
||||||
|
loadid = -1
|
||||||
|
try:
|
||||||
|
tempbody = json.loads(body)
|
||||||
|
loadid = tryparseint(tempbody.get('slot', 0))
|
||||||
|
except Exception:
|
||||||
|
loadid = -1
|
||||||
|
if loadid < 0 or str(loadid) not in savedata_obj:
|
||||||
|
response_body = (json.dumps({"success":False,"data":None}).encode())
|
||||||
|
else:
|
||||||
|
response_body = (json.dumps({"success":True,"data":savedata_obj[str(loadid)]}).encode())
|
||||||
|
|
||||||
|
elif self.path.endswith('/api/extra/data/save'):
|
||||||
|
if not self.secure_endpoint():
|
||||||
|
return
|
||||||
|
if savedata_obj is None:
|
||||||
|
response_code = 400
|
||||||
|
response_body = (json.dumps({"success":False, "error":"SaveDataFile not enabled!"}).encode())
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
incoming_story = json.loads(body) # ensure submitted data is valid json
|
||||||
|
slotid = tryparseint(incoming_story.get('slot', -1))
|
||||||
|
dataformat = incoming_story.get('format', "")
|
||||||
|
title = incoming_story.get('title', "")
|
||||||
|
if not title or title=="":
|
||||||
|
title = "Untitled Save"
|
||||||
|
storybody = incoming_story.get('data', None) #should be a compressed string
|
||||||
|
if slotid >= 0 and slotid < net_save_slots: # we shall provide 4 network save slots
|
||||||
|
saveneeded = False
|
||||||
|
if storybody and storybody!="":
|
||||||
|
storybody = str(storybody)
|
||||||
|
if len(storybody) > (1024*1024*8): #limit story to 8mb
|
||||||
|
response_code = 400
|
||||||
|
response_body = (json.dumps({"success":False, "error":"Story is too long!"}).encode())
|
||||||
|
else:
|
||||||
|
savedata_obj[str(slotid)] = {"title":title, "format":dataformat, "data":storybody}
|
||||||
|
saveneeded = True
|
||||||
|
else: #erasing existing story
|
||||||
|
if str(slotid) in savedata_obj:
|
||||||
|
savedata_obj.pop(str(slotid))
|
||||||
|
saveneeded = True
|
||||||
|
if saveneeded:
|
||||||
|
if args.savedatafile and os.path.exists(args.savedatafile):
|
||||||
|
with open(args.savedatafile, 'w+', encoding='utf-8', errors='ignore') as f:
|
||||||
|
json.dump(savedata_obj, f)
|
||||||
|
print(f"Data was saved to slot {slotid}")
|
||||||
|
response_body = (json.dumps({"success":True, "error":""}).encode())
|
||||||
|
else:
|
||||||
|
response_code = 400
|
||||||
|
response_body = (json.dumps({"success":False, "error":"SaveDataFile is missing!"}).encode())
|
||||||
|
else:
|
||||||
|
response_body = (json.dumps({"success":True, "error":""}).encode())
|
||||||
|
else:
|
||||||
|
response_code = 400
|
||||||
|
response_body = (json.dumps({"success":False, "error":"No story submitted or invalid slot!"}).encode())
|
||||||
|
except Exception as e:
|
||||||
|
utfprint("Remote Save Story - Body Error: " + str(e))
|
||||||
|
response_code = 400
|
||||||
|
response_body = (json.dumps({"success": False, "error":"Submitted story invalid!"}).encode())
|
||||||
|
|
||||||
elif self.path.endswith('/api/extra/multiplayer/getstory'):
|
elif self.path.endswith('/api/extra/multiplayer/getstory'):
|
||||||
if not self.secure_endpoint():
|
if not self.secure_endpoint():
|
||||||
return
|
return
|
||||||
|
@ -3097,7 +3177,7 @@ def show_gui():
|
||||||
global using_gui_launcher
|
global using_gui_launcher
|
||||||
using_gui_launcher = True
|
using_gui_launcher = True
|
||||||
from tkinter.filedialog import askopenfilename, askdirectory
|
from tkinter.filedialog import askopenfilename, askdirectory
|
||||||
from tkinter.filedialog import asksaveasfile
|
from tkinter.filedialog import asksaveasfilename
|
||||||
|
|
||||||
# if args received, launch
|
# if args received, launch
|
||||||
if len(sys.argv) != 1 and not args.showgui:
|
if len(sys.argv) != 1 and not args.showgui:
|
||||||
|
@ -3214,7 +3294,7 @@ def show_gui():
|
||||||
|
|
||||||
tabs = ctk.CTkFrame(root, corner_radius = 0, width=windowwidth, height=windowheight-50)
|
tabs = ctk.CTkFrame(root, corner_radius = 0, width=windowwidth, height=windowheight-50)
|
||||||
tabs.grid(row=0, stick="nsew")
|
tabs.grid(row=0, stick="nsew")
|
||||||
tabnames= ["Quick Launch", "Hardware", "Tokens", "Model Files", "Network", "Horde Worker","Image Gen","Audio","Admin","Extra"]
|
tabnames= ["Quick Launch", "Hardware", "Tokens", "Loaded Files", "Network", "Horde Worker","Image Gen","Audio","Admin","Extra"]
|
||||||
navbuttons = {}
|
navbuttons = {}
|
||||||
navbuttonframe = ctk.CTkFrame(tabs, width=100, height=int(tabs.cget("height")))
|
navbuttonframe = ctk.CTkFrame(tabs, width=100, height=int(tabs.cget("height")))
|
||||||
navbuttonframe.grid(row=0, column=0, padx=2,pady=2)
|
navbuttonframe.grid(row=0, column=0, padx=2,pady=2)
|
||||||
|
@ -3276,6 +3356,7 @@ def show_gui():
|
||||||
lora_var = ctk.StringVar()
|
lora_var = ctk.StringVar()
|
||||||
lora_base_var = ctk.StringVar()
|
lora_base_var = ctk.StringVar()
|
||||||
preloadstory_var = ctk.StringVar()
|
preloadstory_var = ctk.StringVar()
|
||||||
|
savedatafile_var = ctk.StringVar()
|
||||||
mmproj_var = ctk.StringVar()
|
mmproj_var = ctk.StringVar()
|
||||||
visionmaxres_var = ctk.StringVar(value=str(default_visionmaxres))
|
visionmaxres_var = ctk.StringVar(value=str(default_visionmaxres))
|
||||||
draftmodel_var = ctk.StringVar()
|
draftmodel_var = ctk.StringVar()
|
||||||
|
@ -3385,14 +3466,22 @@ def show_gui():
|
||||||
entry.grid(row=row, column=(0 if singleline else 1), padx=padx, sticky="nw")
|
entry.grid(row=row, column=(0 if singleline else 1), padx=padx, sticky="nw")
|
||||||
return entry, label
|
return entry, label
|
||||||
|
|
||||||
def makefileentry(parent, text, searchtext, var, row=0, width=200, filetypes=[], onchoosefile=None, singlerow=False, singlecol=True, is_dir=False, tooltiptxt=""):
|
#file dialog types: 0=openfile,1=savefile,2=opendir
|
||||||
|
def makefileentry(parent, text, searchtext, var, row=0, width=200, filetypes=[], onchoosefile=None, singlerow=False, singlecol=True, dialog_type=0, tooltiptxt=""):
|
||||||
label = makelabel(parent, text, row,0,tooltiptxt,columnspan=3)
|
label = makelabel(parent, text, row,0,tooltiptxt,columnspan=3)
|
||||||
def getfilename(var, text):
|
def getfilename(var, text):
|
||||||
initialDir = os.path.dirname(var.get())
|
initialDir = os.path.dirname(var.get())
|
||||||
initialDir = initialDir if os.path.isdir(initialDir) else None
|
initialDir = initialDir if os.path.isdir(initialDir) else None
|
||||||
fnam = None
|
fnam = None
|
||||||
if is_dir:
|
if dialog_type==2:
|
||||||
fnam = askdirectory(title=text, mustexist=True, initialdir=initialDir)
|
fnam = askdirectory(title=text, mustexist=True, initialdir=initialDir)
|
||||||
|
elif dialog_type==1:
|
||||||
|
fnam = asksaveasfilename(title=text, filetypes=filetypes, defaultextension=filetypes, initialdir=initialDir)
|
||||||
|
if not fnam:
|
||||||
|
fnam = ""
|
||||||
|
else:
|
||||||
|
fnam = str(fnam).strip()
|
||||||
|
fnam = f"{fnam}.jsondb" if ".jsondb" not in fnam.lower() else fnam
|
||||||
else:
|
else:
|
||||||
fnam = askopenfilename(title=text,filetypes=filetypes, initialdir=initialDir)
|
fnam = askopenfilename(title=text,filetypes=filetypes, initialdir=initialDir)
|
||||||
if fnam:
|
if fnam:
|
||||||
|
@ -3777,7 +3866,7 @@ def show_gui():
|
||||||
togglectxshift(1,1,1)
|
togglectxshift(1,1,1)
|
||||||
|
|
||||||
# Model Tab
|
# Model Tab
|
||||||
model_tab = tabcontent["Model Files"]
|
model_tab = tabcontent["Loaded Files"]
|
||||||
|
|
||||||
makefileentry(model_tab, "Text Model:", "Select GGUF or GGML Model File", model_var, 1,width=280,singlerow=True, onchoosefile=on_picked_model_file,tooltiptxt="Select a GGUF or GGML model file on disk to be loaded.")
|
makefileentry(model_tab, "Text Model:", "Select GGUF or GGML Model File", model_var, 1,width=280,singlerow=True, onchoosefile=on_picked_model_file,tooltiptxt="Select a GGUF or GGML model file on disk to be loaded.")
|
||||||
makefileentry(model_tab, "Text Lora:", "Select Lora File",lora_var, 3,width=280,singlerow=True,tooltiptxt="Select an optional GGML Text LoRA adapter to use.\nLeave blank to skip.")
|
makefileentry(model_tab, "Text Lora:", "Select Lora File",lora_var, 3,width=280,singlerow=True,tooltiptxt="Select an optional GGML Text LoRA adapter to use.\nLeave blank to skip.")
|
||||||
|
@ -3789,6 +3878,7 @@ def show_gui():
|
||||||
makelabelentry(model_tab, "Splits: ", draftgpusplit_str_vars, 13, 50,padx=210,singleline=True,tooltip="Distribution of draft model layers. Leave blank to follow main model's gpu split. Only works if multi-gpu (All) selected in main model.", labelpadx=160)
|
makelabelentry(model_tab, "Splits: ", draftgpusplit_str_vars, 13, 50,padx=210,singleline=True,tooltip="Distribution of draft model layers. Leave blank to follow main model's gpu split. Only works if multi-gpu (All) selected in main model.", labelpadx=160)
|
||||||
makelabelentry(model_tab, "Layers: ", draftgpulayers_var, 13, 50,padx=320,singleline=True,tooltip="How many layers to GPU offload for the draft model", labelpadx=270)
|
makelabelentry(model_tab, "Layers: ", draftgpulayers_var, 13, 50,padx=320,singleline=True,tooltip="How many layers to GPU offload for the draft model", labelpadx=270)
|
||||||
makefileentry(model_tab, "Preload Story:", "Select Preloaded Story File", preloadstory_var, 15,width=280,singlerow=True,tooltiptxt="Select an optional KoboldAI JSON savefile \nto be served on launch to any client.")
|
makefileentry(model_tab, "Preload Story:", "Select Preloaded Story File", preloadstory_var, 15,width=280,singlerow=True,tooltiptxt="Select an optional KoboldAI JSON savefile \nto be served on launch to any client.")
|
||||||
|
makefileentry(model_tab, "SaveData File:", "Select or Create New SaveData Database File", savedatafile_var, 17,width=280,filetypes=[("KoboldCpp SaveDB", "*.jsondb")],singlerow=True,dialog_type=1,tooltiptxt="Selecting a file will allow data to be loaded and saved persistently to this KoboldCpp server remotely. File is created if it does not exist.")
|
||||||
makefileentry(model_tab, "ChatCompletions Adapter:", "Select ChatCompletions Adapter File", chatcompletionsadapter_var, 24, width=250, filetypes=[("JSON Adapter", "*.json")], tooltiptxt="Select an optional ChatCompletions Adapter JSON file to force custom instruct tags.")
|
makefileentry(model_tab, "ChatCompletions Adapter:", "Select ChatCompletions Adapter File", chatcompletionsadapter_var, 24, width=250, filetypes=[("JSON Adapter", "*.json")], tooltiptxt="Select an optional ChatCompletions Adapter JSON file to force custom instruct tags.")
|
||||||
def pickpremadetemplate():
|
def pickpremadetemplate():
|
||||||
initialDir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'kcpp_adapters')
|
initialDir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'kcpp_adapters')
|
||||||
|
@ -3909,7 +3999,7 @@ def show_gui():
|
||||||
admin_tab = tabcontent["Admin"]
|
admin_tab = tabcontent["Admin"]
|
||||||
makecheckbox(admin_tab, "Enable Model Administration", admin_var, 1, 0,tooltiptxt="Enable a admin server, allowing you to remotely relaunch and swap models and configs.")
|
makecheckbox(admin_tab, "Enable Model Administration", admin_var, 1, 0,tooltiptxt="Enable a admin server, allowing you to remotely relaunch and swap models and configs.")
|
||||||
makelabelentry(admin_tab, "Admin Password:" , admin_password_var, 3, 150,padx=120,singleline=True,tooltip="Require a password to access admin functions. You are strongly advised to use one for publically accessible instances!")
|
makelabelentry(admin_tab, "Admin Password:" , admin_password_var, 3, 150,padx=120,singleline=True,tooltip="Require a password to access admin functions. You are strongly advised to use one for publically accessible instances!")
|
||||||
makefileentry(admin_tab, "Config Directory:", "Select directory containing .kcpps files to relaunch from", admin_dir_var, 5, width=280, is_dir=True, tooltiptxt="Specify a directory to look for .kcpps configs in, which can be used to swap models.")
|
makefileentry(admin_tab, "Config Directory:", "Select directory containing .kcpps files to relaunch from", admin_dir_var, 5, width=280, dialog_type=2, tooltiptxt="Specify a directory to look for .kcpps configs in, which can be used to swap models.")
|
||||||
|
|
||||||
def kcpp_export_template():
|
def kcpp_export_template():
|
||||||
nonlocal kcpp_exporting_template
|
nonlocal kcpp_exporting_template
|
||||||
|
@ -3937,10 +4027,10 @@ def show_gui():
|
||||||
savdict["draftgpusplit"] = None
|
savdict["draftgpusplit"] = None
|
||||||
savdict["config"] = None
|
savdict["config"] = None
|
||||||
savdict["ttsthreads"] = 0
|
savdict["ttsthreads"] = 0
|
||||||
filename = asksaveasfile(filetypes=file_type, defaultextension=file_type)
|
filename = asksaveasfilename(filetypes=file_type, defaultextension=file_type)
|
||||||
if filename is None:
|
if not filename:
|
||||||
return
|
return
|
||||||
filenamestr = str(filename.name).strip()
|
filenamestr = str(filename).strip()
|
||||||
filenamestr = f"{filenamestr}.kcppt" if ".kcppt" not in filenamestr.lower() else filenamestr
|
filenamestr = f"{filenamestr}.kcppt" if ".kcppt" not in filenamestr.lower() else filenamestr
|
||||||
file = open(filenamestr, 'a')
|
file = open(filenamestr, 'a')
|
||||||
file.write(json.dumps(savdict))
|
file.write(json.dumps(savdict))
|
||||||
|
@ -4067,6 +4157,7 @@ def show_gui():
|
||||||
args.model_param = None if model_var.get() == "" else model_var.get()
|
args.model_param = None if model_var.get() == "" else model_var.get()
|
||||||
args.lora = None if lora_var.get() == "" else ([lora_var.get()] if lora_base_var.get()=="" else [lora_var.get(), lora_base_var.get()])
|
args.lora = None if lora_var.get() == "" else ([lora_var.get()] if lora_base_var.get()=="" else [lora_var.get(), lora_base_var.get()])
|
||||||
args.preloadstory = None if preloadstory_var.get() == "" else preloadstory_var.get()
|
args.preloadstory = None if preloadstory_var.get() == "" else preloadstory_var.get()
|
||||||
|
args.savedatafile = None if savedatafile_var.get() == "" else savedatafile_var.get()
|
||||||
try:
|
try:
|
||||||
if kcpp_exporting_template and isinstance(args.preloadstory, str) and args.preloadstory!="" and os.path.exists(args.preloadstory):
|
if kcpp_exporting_template and isinstance(args.preloadstory, str) and args.preloadstory!="" and os.path.exists(args.preloadstory):
|
||||||
print("Embedding preload story...") # parse and save embedded preload story
|
print("Embedding preload story...") # parse and save embedded preload story
|
||||||
|
@ -4274,6 +4365,7 @@ def show_gui():
|
||||||
|
|
||||||
password_var.set(dict["password"] if ("password" in dict and dict["password"]) else "")
|
password_var.set(dict["password"] if ("password" in dict and dict["password"]) else "")
|
||||||
preloadstory_var.set(dict["preloadstory"] if ("preloadstory" in dict and dict["preloadstory"]) else "")
|
preloadstory_var.set(dict["preloadstory"] if ("preloadstory" in dict and dict["preloadstory"]) else "")
|
||||||
|
savedatafile_var.set(dict["savedatafile"] if ("savedatafile" in dict and dict["savedatafile"]) else "")
|
||||||
chatcompletionsadapter_var.set(dict["chatcompletionsadapter"] if ("chatcompletionsadapter" in dict and dict["chatcompletionsadapter"]) else "")
|
chatcompletionsadapter_var.set(dict["chatcompletionsadapter"] if ("chatcompletionsadapter" in dict and dict["chatcompletionsadapter"]) else "")
|
||||||
port_var.set(dict["port_param"] if ("port_param" in dict and dict["port_param"]) else defaultport)
|
port_var.set(dict["port_param"] if ("port_param" in dict and dict["port_param"]) else defaultport)
|
||||||
host_var.set(dict["host"] if ("host" in dict and dict["host"]) else "")
|
host_var.set(dict["host"] if ("host" in dict and dict["host"]) else "")
|
||||||
|
@ -4324,10 +4416,10 @@ def show_gui():
|
||||||
export_vars()
|
export_vars()
|
||||||
savdict = json.loads(json.dumps(args.__dict__))
|
savdict = json.loads(json.dumps(args.__dict__))
|
||||||
file_type = [("KoboldCpp Settings", "*.kcpps")]
|
file_type = [("KoboldCpp Settings", "*.kcpps")]
|
||||||
filename = asksaveasfile(filetypes=file_type, defaultextension=file_type)
|
filename = asksaveasfilename(filetypes=file_type, defaultextension=file_type)
|
||||||
if filename is None:
|
if not filename:
|
||||||
return
|
return
|
||||||
filenamestr = str(filename.name).strip()
|
filenamestr = str(filename).strip()
|
||||||
filenamestr = f"{filenamestr}.kcpps" if ".kcpps" not in filenamestr.lower() else filenamestr
|
filenamestr = f"{filenamestr}.kcpps" if ".kcpps" not in filenamestr.lower() else filenamestr
|
||||||
file = open(filenamestr, 'a')
|
file = open(filenamestr, 'a')
|
||||||
file.write(json.dumps(savdict))
|
file.write(json.dumps(savdict))
|
||||||
|
@ -5282,7 +5374,7 @@ def kcpp_main_process(launch_args, g_memory=None, gui_launcher=False):
|
||||||
friendlymodelname = "koboldcpp/" + sanitize_string(newmdldisplayname)
|
friendlymodelname = "koboldcpp/" + sanitize_string(newmdldisplayname)
|
||||||
|
|
||||||
# horde worker settings
|
# horde worker settings
|
||||||
global maxhordelen, maxhordectx, showdebug, has_multiplayer
|
global maxhordelen, maxhordectx, showdebug, has_multiplayer, savedata_obj
|
||||||
if args.hordemodelname and args.hordemodelname!="":
|
if args.hordemodelname and args.hordemodelname!="":
|
||||||
friendlymodelname = args.hordemodelname
|
friendlymodelname = args.hordemodelname
|
||||||
if args.debugmode == 1:
|
if args.debugmode == 1:
|
||||||
|
@ -5303,6 +5395,25 @@ def kcpp_main_process(launch_args, g_memory=None, gui_launcher=False):
|
||||||
if args.multiplayer:
|
if args.multiplayer:
|
||||||
has_multiplayer = True
|
has_multiplayer = True
|
||||||
|
|
||||||
|
if args.savedatafile and isinstance(args.savedatafile, str):
|
||||||
|
filepath = args.savedatafile
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r+', encoding='utf-8', errors='ignore') as f:
|
||||||
|
loaded = json.load(f)
|
||||||
|
savedata_obj = loaded
|
||||||
|
print(f"Loaded existing savedatafile at '{filepath}'.")
|
||||||
|
except FileNotFoundError:
|
||||||
|
try:
|
||||||
|
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||||
|
with open(filepath, 'w+', encoding='utf-8', errors='ignore') as f:
|
||||||
|
savedata_obj = {}
|
||||||
|
print(f"File '{filepath}' did not exist. Created new savedatafile.")
|
||||||
|
json.dump(savedata_obj, f)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to create savedatafile '{filepath}': {e}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to access savedatafile '{filepath}': {e}")
|
||||||
|
|
||||||
if args.highpriority:
|
if args.highpriority:
|
||||||
print("Setting process to Higher Priority - Use Caution")
|
print("Setting process to Higher Priority - Use Caution")
|
||||||
try:
|
try:
|
||||||
|
@ -5812,6 +5923,7 @@ if __name__ == '__main__':
|
||||||
advparser.add_argument("--highpriority", help="Experimental flag. If set, increases the process CPU priority, potentially speeding up generation. Use caution.", action='store_true')
|
advparser.add_argument("--highpriority", help="Experimental flag. If set, increases the process CPU priority, potentially speeding up generation. Use caution.", action='store_true')
|
||||||
advparser.add_argument("--foreground", help="Windows only. Sends the terminal to the foreground every time a new prompt is generated. This helps avoid some idle slowdown issues.", action='store_true')
|
advparser.add_argument("--foreground", help="Windows only. Sends the terminal to the foreground every time a new prompt is generated. This helps avoid some idle slowdown issues.", action='store_true')
|
||||||
advparser.add_argument("--preloadstory", metavar=('[savefile]'), help="Configures a prepared story json save file to be hosted on the server, which frontends (such as KoboldAI Lite) can access over the API.", default="")
|
advparser.add_argument("--preloadstory", metavar=('[savefile]'), help="Configures a prepared story json save file to be hosted on the server, which frontends (such as KoboldAI Lite) can access over the API.", default="")
|
||||||
|
advparser.add_argument("--savedatafile", metavar=('[savefile]'), help="If enabled, creates or opens a persistent database file on the server, that allows users to save and load their data remotely.", default="")
|
||||||
advparser.add_argument("--quiet", help="Enable quiet mode, which hides generation inputs and outputs in the terminal. Quiet mode is automatically enabled when running a horde worker.", action='store_true')
|
advparser.add_argument("--quiet", help="Enable quiet mode, which hides generation inputs and outputs in the terminal. Quiet mode is automatically enabled when running a horde worker.", action='store_true')
|
||||||
advparser.add_argument("--ssl", help="Allows all content to be served over SSL instead. A valid UNENCRYPTED SSL cert and key .pem files must be provided", metavar=('[cert_pem]', '[key_pem]'), nargs='+')
|
advparser.add_argument("--ssl", help="Allows all content to be served over SSL instead. A valid UNENCRYPTED SSL cert and key .pem files must be provided", metavar=('[cert_pem]', '[key_pem]'), nargs='+')
|
||||||
advparser.add_argument("--nocertify", help="Allows insecure SSL connections. Use this if you have cert errors and need to bypass certificate restrictions.", action='store_true')
|
advparser.add_argument("--nocertify", help="Allows insecure SSL connections. Use this if you have cert errors and need to bypass certificate restrictions.", action='store_true')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue