mirror of
https://github.com/LostRuins/koboldcpp.git
synced 2025-09-10 17:14:36 +00:00
updated docs, fixed a few issues with multiplayer
This commit is contained in:
parent
232e4d2c38
commit
c2ca2ec2bc
3 changed files with 163 additions and 33 deletions
123
kcpp_docs.embd
123
kcpp_docs.embd
|
@ -411,7 +411,7 @@
|
|||
"info": {
|
||||
"title": "KoboldCpp API",
|
||||
"description": "For swagger.json, <a href=\"?json=1\">click here</a>.",
|
||||
"version": "1.61"
|
||||
"version": "1.79"
|
||||
},
|
||||
"openapi": "3.0.3",
|
||||
"paths": {
|
||||
|
@ -610,10 +610,12 @@
|
|||
"application/json": {
|
||||
"example": {
|
||||
"result": "KoboldCpp",
|
||||
"version": "1.61",
|
||||
"version": "1.79",
|
||||
"protected": false,
|
||||
"txt2img": false,
|
||||
"vision": false
|
||||
"vision": false,
|
||||
"transcribe":false,
|
||||
"multiplayer": false,
|
||||
},
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/KcppVersion"
|
||||
|
@ -684,6 +686,121 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/api/extra/multiplayer/status": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"example": {"turn_major": 0, "turn_minor": 0, "idle": 1, "data_format":""},
|
||||
"schema": {
|
||||
"properties": {
|
||||
"turn_major": {"type": "string"},
|
||||
"turn_minor": {"type": "string"},
|
||||
"idle": {"type": "number"},
|
||||
"data_format": {"type": "string"},
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Successful request"
|
||||
}
|
||||
},
|
||||
"description": "Fetches the current multiplayer turn information. Only useful for Multiplayer sessions in KoboldAI Lite.",
|
||||
"summary": "Fetches the current multiplayer turn information.",
|
||||
"tags": [
|
||||
"api/extra"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/extra/multiplayer/getstory": {
|
||||
"get": {
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"text/plain": {
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"example": "base64_lzma_str"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Successful request"
|
||||
}
|
||||
},
|
||||
"description": "Fetches the current multiplayer story data, LZMA compressed encoded base64. Data is usually in the same format is KAI Lite compressed savefiles.",
|
||||
"summary": "Fetches the current multiplayer story data, LZMA compressed encoded base64",
|
||||
"tags": [
|
||||
"api/extra"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/extra/multiplayer/setstory": {
|
||||
"post": {
|
||||
"description": "Sets the current multiplayer story and increments the turn.",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"example": {
|
||||
"full_update": true,
|
||||
"data_format": "kcpp_lzma_b64",
|
||||
"data": "base64_lzma_str",
|
||||
},
|
||||
"schema": {
|
||||
"properties": {
|
||||
"full_update": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"data_format": {
|
||||
"type": "string"
|
||||
},
|
||||
"data": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": false
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"example": {
|
||||
"results": [
|
||||
{
|
||||
"success": true,
|
||||
"turn_major": 1,
|
||||
"turn_minor": 0,
|
||||
"idle": 1,
|
||||
"data_format":"",
|
||||
}
|
||||
]
|
||||
},
|
||||
"schema": {
|
||||
"properties": {
|
||||
"success": {"type": "boolean"},
|
||||
"turn_major": {"type": "string"},
|
||||
"turn_minor": {"type": "string"},
|
||||
"idle": {"type": "number"},
|
||||
"data_format": {"type": "string"},
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Successful request"
|
||||
}
|
||||
},
|
||||
"summary": "Sets the current multiplayer story and increments the turn.",
|
||||
"tags": [
|
||||
"api/extra"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/extra/generate/stream": {
|
||||
"post": {
|
||||
"description": "Generates text given a prompt and generation settings, with SSE streaming.\n\nUnspecified values are set to defaults.\n\nSSE streaming establishes a persistent connection, returning ongoing process in the form of message events.\n\n``` \nevent: message\ndata: {data}\n\n```",
|
||||
|
|
15
klite.embd
15
klite.embd
|
@ -12,7 +12,7 @@ Current version indicated by LITEVER below.
|
|||
-->
|
||||
|
||||
<script>
|
||||
const LITEVER = 189;
|
||||
const LITEVER = 190;
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
var localflag = true;
|
||||
const STORAGE_PREFIX = (localflag?"e_":"")+"kaihordewebui_";
|
||||
|
@ -4291,6 +4291,7 @@ Current version indicated by LITEVER below.
|
|||
var koboldcpp_has_vision = false;
|
||||
var koboldcpp_has_multiplayer = false;
|
||||
var multiplayer_active = false;
|
||||
var multiplayer_pinged = false;
|
||||
var multiplayer_override_name = "";
|
||||
var multiplayer_last_turn_major = 0;
|
||||
var multiplayer_last_turn_minor = 0;
|
||||
|
@ -7496,6 +7497,7 @@ Current version indicated by LITEVER below.
|
|||
|
||||
function leave_multiplayer()
|
||||
{
|
||||
multiplayer_pinged = false;
|
||||
multiplayer_active = false;
|
||||
multiplayer_last_turn_major = 0;
|
||||
multiplayer_last_turn_minor = 0;
|
||||
|
@ -7512,6 +7514,7 @@ Current version indicated by LITEVER below.
|
|||
inputBox(`You're about to enter a Multiplayer Session.<br><br><span class="color_red">Note that stories or messages sent by other users are <b>unfiltered</b>, and may contain <b>offensive or disturbing content</b>. You assume full responsibility and participate at your own discretion.</span><br><br>Enter a unique nickname to use for chat mode (only yourself), or leave it blank to share the same common chatname with other users.`,"Join Multiplayer - Override Chat Nickname?","","[No Override]", ()=>{
|
||||
let userinput = getInputBoxValue().trim();
|
||||
multiplayer_active = true;
|
||||
multiplayer_pinged = false;
|
||||
multiplayer_override_name = userinput;
|
||||
multiplayer_last_turn_major = 0;
|
||||
multiplayer_last_turn_minor = 0;
|
||||
|
@ -7556,8 +7559,9 @@ Current version indicated by LITEVER below.
|
|||
method: 'POST',
|
||||
headers: get_kobold_header(),
|
||||
body: JSON.stringify({
|
||||
"fullupdate": fullupdate,
|
||||
"full_update": fullupdate,
|
||||
"data": subdata,
|
||||
"data_format":"kcpp_lzma_b64",
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
|
@ -15106,6 +15110,11 @@ Current version indicated by LITEVER below.
|
|||
})
|
||||
.then(response => response.json())
|
||||
.then(vals => {
|
||||
if(!multiplayer_pinged)
|
||||
{
|
||||
multiplayer_pinged = true;
|
||||
render_gametext(false);
|
||||
}
|
||||
if(vals && vals.turn_major && multiplayer_active && (vals.turn_major != multiplayer_last_turn_major || vals.turn_minor != multiplayer_last_turn_minor))
|
||||
{
|
||||
let minor_change = (multiplayer_last_turn_major == vals.turn_major);
|
||||
|
@ -15836,7 +15845,7 @@ Current version indicated by LITEVER below.
|
|||
document.getElementById("gametext").innerHTML = `Welcome to <span class="color_cyan">KoboldAI Lite</span>!`+
|
||||
`<br>You are using the models <span class="color_green">${selmodelstr}</span>${(selected_workers.length == 0 ? `` : ` (Pinned to ${selected_workers.length} worker IDs)`)}.`+
|
||||
`${whorun}.`+
|
||||
(multiplayer_active?`<br><br><span class="color_green">[ Multiplayer is <b>Active</b>! This session is shared with other server participants.]<br>[ You can leave via exit button in top right corner. ]</span>`:(is_using_kcpp_with_multiplayer()?`<br><br>[ <a href="#" tabindex="${mainmenu_is_untab?`-1`:`0`}" class="color_blueurl mainnav" onclick="join_multiplayer()"><span class="color_green">Multiplayer Available</span> - Click Here To Join</a> ]`:``))+
|
||||
(multiplayer_active?(!multiplayer_pinged?`<br><br><span class="color_orange">[ Trying to join Multiplayer... ]</span>`:`<br><br><span class="color_green">[ Multiplayer is <b>Active</b>! This session is shared with other server participants.]<br>[ You can leave via exit button in top right corner. ]</span>`):(is_using_kcpp_with_multiplayer()?`<br><br>[ <a href="#" tabindex="${mainmenu_is_untab?`-1`:`0`}" class="color_blueurl mainnav" onclick="join_multiplayer()"><span class="color_green">Multiplayer Available</span> - Click Here To Join</a> ]`:``))+
|
||||
`<br><br><b><span class="color_orange">${nowmode} Selected</span></b> - Enter a prompt below to begin!`+
|
||||
`<br>Or, <a href="#" tabindex="${mainmenu_is_untab?`-1`:`0`}" class="color_blueurl mainnav" onclick="document.getElementById('loadfileinput').click()">load a <b>JSON File</b> or a <b>Character Card</b> here.</a>`+
|
||||
`<br>Or, <a href="#" tabindex="${mainmenu_is_untab?`-1`:`0`}" class="color_blueurl mainnav" onclick="display_scenarios()">select a <b>Quick Start Scenario</b> here.</a>`+
|
||||
|
|
58
koboldcpp.py
58
koboldcpp.py
|
@ -68,6 +68,7 @@ has_multiplayer = False
|
|||
multiplayer_story_data_compressed = None #stores the full compressed story of the current multiplayer session
|
||||
multiplayer_turn_major = 0 # to keep track of when a client needs to sync their stories
|
||||
multiplayer_turn_minor = 0
|
||||
multiplayer_dataformat = "" # used to tell what is the data payload in saved story. set by client
|
||||
preloaded_story = None
|
||||
chatcompl_adapter = None
|
||||
embedded_kailite = None
|
||||
|
@ -1797,7 +1798,7 @@ Enter Prompt:<br>
|
|||
|
||||
def do_GET(self):
|
||||
global embedded_kailite, embedded_kcpp_docs, embedded_kcpp_sdui
|
||||
global has_multiplayer, multiplayer_turn_major, multiplayer_turn_minor, multiplayer_story_data_compressed, maxctx, maxhordelen, friendlymodelname, KcppVersion, totalgens, preloaded_story, exitcounter, currentusergenkey, friendlysdmodelname, fullsdmodelpath, mmprojpath, password, fullwhispermodelpath
|
||||
global has_multiplayer, multiplayer_turn_major, multiplayer_turn_minor, multiplayer_story_data_compressed, multiplayer_dataformat, maxctx, maxhordelen, friendlymodelname, KcppVersion, totalgens, preloaded_story, exitcounter, currentusergenkey, friendlysdmodelname, fullsdmodelpath, mmprojpath, password, fullwhispermodelpath
|
||||
self.path = self.path.rstrip('/')
|
||||
response_body = None
|
||||
content_type = 'application/json'
|
||||
|
@ -1941,13 +1942,13 @@ Enter Prompt:<br>
|
|||
if not has_multiplayer:
|
||||
response_body = (json.dumps({"error":"Multiplayer not enabled!"}).encode())
|
||||
else:
|
||||
response_body = (json.dumps({"turn_major":multiplayer_turn_major,"turn_minor":multiplayer_turn_minor,"idle":(0 if modelbusy.locked() else 1)}).encode())
|
||||
response_body = (json.dumps({"turn_major":multiplayer_turn_major,"turn_minor":multiplayer_turn_minor,"idle":(0 if modelbusy.locked() else 1),"data_format":multiplayer_dataformat}).encode())
|
||||
|
||||
elif self.path=="/api/extra/multiplayer/getstory":
|
||||
if not has_multiplayer:
|
||||
response_body = (json.dumps({"error":"Multiplayer not enabled!"}).encode())
|
||||
response_body = ("".encode())
|
||||
elif multiplayer_story_data_compressed is None:
|
||||
response_body = (json.dumps({"gamestarted":True,"prompt":"","memory":"","authorsnote":"","anotetemplate":"","actions":[],"actions_metadata":{},"worldinfo":[],"wifolders_d":{},"wifolders_l":[]}).encode())
|
||||
response_body = ("".encode())
|
||||
else:
|
||||
response_body = multiplayer_story_data_compressed.encode()
|
||||
|
||||
|
@ -1976,7 +1977,7 @@ Enter Prompt:<br>
|
|||
return
|
||||
|
||||
def do_POST(self):
|
||||
global modelbusy, requestsinqueue, currentusergenkey, totalgens, pendingabortkey, multiplayer_turn_major, multiplayer_turn_minor, multiplayer_story_data_compressed
|
||||
global modelbusy, requestsinqueue, currentusergenkey, totalgens, pendingabortkey, multiplayer_turn_major, multiplayer_turn_minor, multiplayer_story_data_compressed, multiplayer_dataformat
|
||||
contlenstr = self.headers['content-length']
|
||||
content_length = 0
|
||||
body = None
|
||||
|
@ -2078,30 +2079,33 @@ Enter Prompt:<br>
|
|||
if not has_multiplayer:
|
||||
response_code = 400
|
||||
response_body = (json.dumps({"success":False, "error":"Multiplayer not enabled!"}).encode())
|
||||
try:
|
||||
incoming_story = json.loads(body) # ensure submitted data is valid json
|
||||
fullupdate = incoming_story.get('fullupdate', False)
|
||||
storybody = incoming_story.get('data', None) #should be a compressed string
|
||||
if storybody:
|
||||
storybody = str(storybody)
|
||||
if len(storybody) > (1024*1024*3): #limit story to 3mb
|
||||
response_code = 400
|
||||
response_body = (json.dumps({"success":False, "error":"Story is too long!"}).encode())
|
||||
else:
|
||||
multiplayer_story_data_compressed = str(storybody) #save latest story
|
||||
if fullupdate:
|
||||
multiplayer_turn_minor = 0
|
||||
multiplayer_turn_major += 1
|
||||
else:
|
||||
try:
|
||||
incoming_story = json.loads(body) # ensure submitted data is valid json
|
||||
fullupdate = incoming_story.get('full_update', False)
|
||||
dataformat = incoming_story.get('data_format', "")
|
||||
storybody = incoming_story.get('data', None) #should be a compressed string
|
||||
if storybody:
|
||||
storybody = str(storybody)
|
||||
if len(storybody) > (1024*1024*3): #limit story to 3mb
|
||||
response_code = 400
|
||||
response_body = (json.dumps({"success":False, "error":"Story is too long!"}).encode())
|
||||
else:
|
||||
multiplayer_turn_minor += 1
|
||||
response_body = (json.dumps({"success":True,"turn_major":multiplayer_turn_major,"turn_minor":multiplayer_turn_minor}).encode())
|
||||
else:
|
||||
multiplayer_story_data_compressed = str(storybody) #save latest story
|
||||
multiplayer_dataformat = dataformat
|
||||
if fullupdate:
|
||||
multiplayer_turn_minor = 0
|
||||
multiplayer_turn_major += 1
|
||||
else:
|
||||
multiplayer_turn_minor += 1
|
||||
response_body = (json.dumps({"success":True,"turn_major":multiplayer_turn_major,"turn_minor":multiplayer_turn_minor,"idle":(0 if modelbusy.locked() else 1),"data_format":multiplayer_dataformat}).encode())
|
||||
else:
|
||||
response_code = 400
|
||||
response_body = (json.dumps({"success":False, "error":"No story submitted!"}).encode())
|
||||
except Exception as e:
|
||||
utfprint("Multiplayer Set Story - Body Error: " + str(e))
|
||||
response_code = 400
|
||||
response_body = (json.dumps({"success":False, "error":"No story submitted!"}).encode())
|
||||
except Exception as e:
|
||||
utfprint("Multiplayer Set Story - Body Error: " + str(e))
|
||||
response_code = 400
|
||||
response_body = (json.dumps({"success": False, "error":"Submitted story invalid!"}).encode())
|
||||
response_body = (json.dumps({"success": False, "error":"Submitted story invalid!"}).encode())
|
||||
|
||||
if response_body is not None:
|
||||
self.send_response(response_code)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue