Instead of "version" and "koboldVersion", have "koboldUnitedVersion" and
"koboldCppVersion", the latter of which is null if we're not connected
to KoboldCpp.
We now track the loop counter as a parameter of Generate that we
decrement with every recursive call, rather than a global variable,
and it *should* now work with quiet prompt generation.
Generate(), being async, now returns a promise-within-a-promise.
If called with `let p = await Generate(...)`, it'll wait for generation
to *start*. If you then `await p`, you'll wait for generation to
*finish*. This makes it much easier to tell exactly when generation's
done. generateGroupWrapper has been similarly modified.
Status code 401 resets the client Basic auth, so we replace it with 400. This can produce an interesting artifact as "400 Unauthorized", but it's not out of spec.
"The reason phrases listed here are only recommendations -- they can be replaced by local equivalents or left out altogether without affecting the protocol."
https://www.rfc-editor.org/rfc/rfc9110.html#name-overview-of-status-codes
I searched for all users of tokenizers.API, but missed that the menu
converts the numerical select values directly to enum values. I've used
the special tokenizer value 98 to represent "the tokenizer API for
whichever backend we're currently using".
Sorting with a random comparator doesn't actually shuffle an array.
Depending on the sorting algorithm used, there will be a bias to the
shuffle (see https://bost.ocks.org/mike/shuffle/compare.html).
If you open that link in Firefox, the bias will be especially bad.
Instead of implementing "random" character sort using a random sort
comparator, use the shuffle function instead.
Since we already have a template cache, it makes sense to store the
templates in it *after* compiling them, to avoid the overhead of
re-compiling them every time we call renderTemplate.
I've also changed the cache from an object to a Map--it's more
semantically correct, and avoids weird edge cases like a template named
"hasOwnProperty" or some other function that exists as an object
property.
This means we don't have to pass the "padding" parameter into every
function so they can add the padding themselves--we can do it in just
one place instead.