mirror of
https://github.com/KoboldAI/KoboldAI-Client.git
synced 2025-02-23 06:57:44 +01:00
Add token usage indicator
This commit is contained in:
parent
77e2a7972c
commit
555ca5fd05
31
aiserver.py
31
aiserver.py
@ -3608,6 +3608,37 @@ def get_message(msg):
|
|||||||
emit('from_server', {'cmd': 'set_debug', 'data': msg['data']}, broadcast=True)
|
emit('from_server', {'cmd': 'set_debug', 'data': msg['data']}, broadcast=True)
|
||||||
if vars.debug:
|
if vars.debug:
|
||||||
send_debug()
|
send_debug()
|
||||||
|
elif(msg['cmd'] == 'getfieldbudget'):
|
||||||
|
unencoded = msg["data"]["unencoded"]
|
||||||
|
field = msg["data"]["field"]
|
||||||
|
|
||||||
|
# Tokenizer may be undefined here when a model has not been chosen.
|
||||||
|
if "tokenizer" not in globals():
|
||||||
|
# We don't have a tokenizer, just return nulls.
|
||||||
|
emit(
|
||||||
|
'from_server',
|
||||||
|
{'cmd': 'showfieldbudget', 'data': {"length": None, "max": None, "field": field}},
|
||||||
|
broadcast=True
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
header_length = len(tokenizer._koboldai_header)
|
||||||
|
max_tokens = vars.max_length - header_length - vars.sp_length - vars.genamt
|
||||||
|
|
||||||
|
if not unencoded:
|
||||||
|
# Unencoded is empty, just return 0
|
||||||
|
emit(
|
||||||
|
'from_server',
|
||||||
|
{'cmd': 'showfieldbudget', 'data': {"length": 0, "max": max_tokens, "field": field}},
|
||||||
|
broadcast=True
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
tokens_length = len(tokenizer.encode(unencoded))
|
||||||
|
emit(
|
||||||
|
'from_server',
|
||||||
|
{'cmd': 'showfieldbudget', 'data': {"length": tokens_length, "max": max_tokens, "field": field}},
|
||||||
|
broadcast=True
|
||||||
|
)
|
||||||
|
|
||||||
#==================================================================#
|
#==================================================================#
|
||||||
# Send userscripts list to client
|
# Send userscripts list to client
|
||||||
|
@ -512,6 +512,16 @@ function addWiLine(ob) {
|
|||||||
$(".wisortable-excluded-dynamic").removeClass("wisortable-excluded-dynamic");
|
$(".wisortable-excluded-dynamic").removeClass("wisortable-excluded-dynamic");
|
||||||
$(this).parent().css("max-height", "").find(".wicomment").find(".form-control").css("max-height", "");
|
$(this).parent().css("max-height", "").find(".wicomment").find(".form-control").css("max-height", "");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const wientry of document.getElementsByClassName("wientry")) {
|
||||||
|
// If we are uninitialized, skip.
|
||||||
|
if ($(wientry).closest(".wilistitem-uninitialized").length) continue;
|
||||||
|
|
||||||
|
// add() will not add if the class is already present
|
||||||
|
wientry.classList.add("tokens-counted");
|
||||||
|
}
|
||||||
|
|
||||||
|
registerTokenCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWiFolder(uid, ob) {
|
function addWiFolder(uid, ob) {
|
||||||
@ -835,6 +845,7 @@ function exitMemoryMode() {
|
|||||||
button_actmem.html("Memory");
|
button_actmem.html("Memory");
|
||||||
show([button_actback, button_actfwd, button_actretry, button_actwi]);
|
show([button_actback, button_actfwd, button_actretry, button_actwi]);
|
||||||
input_text.val("");
|
input_text.val("");
|
||||||
|
updateInputBudget(input_text[0]);
|
||||||
// Hide Author's Note field
|
// Hide Author's Note field
|
||||||
anote_menu.slideUp("fast");
|
anote_menu.slideUp("fast");
|
||||||
}
|
}
|
||||||
@ -2139,6 +2150,31 @@ function interpolateRGB(color0, color1, t) {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateInputBudget(inputElement) {
|
||||||
|
socket.send({"cmd": "getfieldbudget", "data": {"unencoded": inputElement.value, "field": inputElement.id}});
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerTokenCounters() {
|
||||||
|
// Add token counters to all input containers with the class of "tokens-counted",
|
||||||
|
// if a token counter is not already a child of said container.
|
||||||
|
for (const el of document.getElementsByClassName("tokens-counted")) {
|
||||||
|
if (el.getElementsByClassName("input-token-usage").length) continue;
|
||||||
|
|
||||||
|
let span = document.createElement("span");
|
||||||
|
span.classList.add("input-token-usage");
|
||||||
|
span.innerText = "?/? Tokens";
|
||||||
|
el.appendChild(span);
|
||||||
|
|
||||||
|
let inputElement = el.querySelector("input, textarea");
|
||||||
|
|
||||||
|
inputElement.addEventListener("input", function() {
|
||||||
|
updateInputBudget(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
updateInputBudget(inputElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=================================================================//
|
//=================================================================//
|
||||||
// READY/RUNTIME
|
// READY/RUNTIME
|
||||||
//=================================================================//
|
//=================================================================//
|
||||||
@ -2481,6 +2517,7 @@ $(document).ready(function(){
|
|||||||
memorytext = msg.data;
|
memorytext = msg.data;
|
||||||
input_text.val(msg.data);
|
input_text.val(msg.data);
|
||||||
}
|
}
|
||||||
|
updateInputBudget(input_text[0]);
|
||||||
} else if(msg.cmd == "setmemory") {
|
} else if(msg.cmd == "setmemory") {
|
||||||
memorytext = msg.data;
|
memorytext = msg.data;
|
||||||
if(memorymode) {
|
if(memorymode) {
|
||||||
@ -2602,6 +2639,7 @@ $(document).ready(function(){
|
|||||||
} else if(msg.cmd == "setanote") {
|
} else if(msg.cmd == "setanote") {
|
||||||
// Set contents of Author's Note field
|
// Set contents of Author's Note field
|
||||||
anote_input.val(msg.data);
|
anote_input.val(msg.data);
|
||||||
|
updateInputBudget(anote_input[0]);
|
||||||
} else if(msg.cmd == "setanotetemplate") {
|
} else if(msg.cmd == "setanotetemplate") {
|
||||||
// Set contents of Author's Note Template field
|
// Set contents of Author's Note Template field
|
||||||
$("#anotetemplate").val(msg.data);
|
$("#anotetemplate").val(msg.data);
|
||||||
@ -2913,6 +2951,12 @@ $(document).ready(function(){
|
|||||||
opt.innerHTML = engine[1];
|
opt.innerHTML = engine[1];
|
||||||
$("#oaimodel")[0].appendChild(opt);
|
$("#oaimodel")[0].appendChild(opt);
|
||||||
}
|
}
|
||||||
|
} else if(msg.cmd == 'showfieldbudget') {
|
||||||
|
let inputElement = document.getElementById(msg.data.field);
|
||||||
|
let tokenBudgetElement = inputElement.parentNode.getElementsByClassName("input-token-usage")[0];
|
||||||
|
let tokenLength = msg.data.length ?? "?";
|
||||||
|
let tokenMax = msg.data.max ?? "?";
|
||||||
|
tokenBudgetElement.innerText = `${tokenLength}/${tokenMax} Tokens`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3381,6 +3425,11 @@ $(document).ready(function(){
|
|||||||
|
|
||||||
if (handled) ev.preventDefault();
|
if (handled) ev.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerTokenCounters();
|
||||||
|
|
||||||
|
updateInputBudget(input_text[0]);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -1695,3 +1695,30 @@ body.connected .popupfooter, .popupfooter.always-available {
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tokens-counted {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-token-usage {
|
||||||
|
color: white;
|
||||||
|
position: absolute;
|
||||||
|
font-size: 10px;
|
||||||
|
bottom: 2px;
|
||||||
|
right: 5px;
|
||||||
|
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override needed here due to the 10px right padding on inputrowleft; add 10 px. */
|
||||||
|
#inputrowleft > .input-token-usage {
|
||||||
|
right: 15px;
|
||||||
|
bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wientry > .input-token-usage {
|
||||||
|
bottom: 8px;
|
||||||
|
}
|
@ -157,7 +157,7 @@
|
|||||||
<div id="inputrowmode">
|
<div id="inputrowmode">
|
||||||
<button type="button" class="btn btn-secondary hidden" id="btnmode">Mode:<br/><b id="btnmode_label">Story</b></button>
|
<button type="button" class="btn btn-secondary hidden" id="btnmode">Mode:<br/><b id="btnmode_label">Story</b></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="inputrowleft">
|
<div id="inputrowleft" class="tokens-counted">
|
||||||
<textarea class="form-control" id="input_text" placeholder="Enter text here"></textarea>
|
<textarea class="form-control" id="input_text" placeholder="Enter text here"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div id="inputrowright">
|
<div id="inputrowright">
|
||||||
@ -170,7 +170,7 @@
|
|||||||
<div class="anotelabel no-padding">
|
<div class="anotelabel no-padding">
|
||||||
Author's Note
|
Author's Note
|
||||||
</div>
|
</div>
|
||||||
<div class="anotefield">
|
<div class="anotefield tokens-counted">
|
||||||
<textarea class="form-control" placeholder="Author's Note" id="anoteinput"></textarea>
|
<textarea class="form-control" placeholder="Author's Note" id="anoteinput"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user