View Horde kudos

This commit is contained in:
SillyLossy
2023-05-21 02:55:47 +03:00
parent 91315b4a74
commit 71d1688dfa
3 changed files with 92 additions and 44 deletions

View File

@ -1023,6 +1023,9 @@
<h5>Get it here: <a target="_blank" href="https://horde.koboldai.net/register">Register</a><br>
Enter <span class="monospace">0000000000</span> to use anonymous mode.
</h5>
<div>
<a id="horde_kudos" href="javascript:void(0);">View my Kudos</a>
</div>
<div class="flex-container">
<input id="horde_api_key" name="horde_api_key" class="text_pole flex1" maxlength="500" type="text" placeholder="0000000000" autocomplete="off">
<div title="Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_horde"></div>
@ -2644,7 +2647,7 @@
<script>
// Configure toast library:
toastr.options.escapeHtml = true; // Prevent raw HTML inserts
toastr.options.escapeHtml = false; // Prevent raw HTML inserts
toastr.options.timeOut = 4000; // How long the toast will display without user interaction
toastr.options.extendedTimeOut = 10000; // How long the toast will display after a user hovers over it
toastr.options.progressBar = true; // Visually indicate how long before a toast expires.

View File

@ -185,6 +185,28 @@ function loadHordeSettings(settings) {
$('#horde_auto_adjust_context_length').prop("checked", horde_settings.auto_adjust_context_length);
}
async function showKudos() {
const response = await fetch('/horde_userinfo', {
method: 'POST',
headers: getRequestHeaders(),
});
if (!response.ok) {
toastr.warning('Could not load user info from Horde. Please try again later.');
return;
}
const data = await response.json();
if (data.anonymous) {
toastr.info('You are in anonymous mode. Set your personal Horde API key to see kudos.')
return;
}
console.log('Horde user data', data);
toastr.info(`${data.username}<br>Kudos: ${data.kudos}`);
}
jQuery(function () {
$("#use_horde").on("input", async function () {
horde_settings.use_horde = !!$(this).prop("checked");
@ -225,4 +247,5 @@ jQuery(function () {
});
$("#horde_refresh").on("click", getHordeModels);
})
$("#horde_kudos").on("click", showKudos);
})

106
server.js
View File

@ -125,7 +125,7 @@ let response_generate_openai;
let response_getstatus_openai;
//RossAscends: Added function to format dates used in files and chat timestamps to a humanized format.
//Mostly I wanted this to be for file names, but couldn't figure out exactly where the filename save code was as everything seemed to be connected.
//Mostly I wanted this to be for file names, but couldn't figure out exactly where the filename save code was as everything seemed to be connected.
//During testing, this performs the same as previous date.now() structure.
//It also does not break old characters/chats, as the code just uses whatever timestamp exists in the chat.
//New chats made with characters will use this new formatting.
@ -898,12 +898,12 @@ async function charaWrite(img_url, data, target_img, response = undefined, mes =
async function tryReadImage(img_url, crop) {
try {
let rawImg = await jimp.read(img_url);
// Apply crop if defined
if (typeof crop == 'object' && [crop.x, crop.y, crop.width, crop.height].every(x => typeof x === 'number')) {
rawImg = rawImg.crop(crop.x, crop.y, crop.width, crop.height);
}
const image = await rawImg.cover(AVATAR_WIDTH, AVATAR_HEIGHT).getBufferAsync(jimp.MIME_PNG);
return image;
}
@ -1351,7 +1351,7 @@ function getImages(path) {
.sort(Intl.Collator().compare);
}
//***********Novel.ai API
//***********Novel.ai API
app.post("/getstatus_novelai", jsonParser, function (request, response_getstatus_novel = response) {
@ -2921,54 +2921,76 @@ app.post('/horde_models', jsonParser, async (_, response) => {
response.send(models);
});
app.post('/horde_userinfo', jsonParser, async (_, response) => {
const api_key_horde = readSecret(SECRET_KEYS.HORDE);
if (!api_key_horde) {
return response.send({ anonymous: true });
}
try {
const user = await ai_horde.findUser({ token: api_key_horde });
return response.send(user);
} catch (error) {
console.error(error);
return response.sendStatus(500);
}
})
app.post('/horde_generateimage', jsonParser, async (request, response) => {
const MAX_ATTEMPTS = 100;
const CHECK_INTERVAL = 3000;
const api_key_horde = readSecret(SECRET_KEYS.HORDE) || ANONYMOUS_KEY;
console.log('Stable Horde request:', request.body);
const generation = await ai_horde.postAsyncImageGenerate(
{
prompt: `${request.body.prompt_prefix} ${request.body.prompt} ### ${request.body.negative_prompt}`,
params:
try {
const generation = await ai_horde.postAsyncImageGenerate(
{
sampler_name: request.body.sampler,
hires_fix: request.body.enable_hr,
use_gfpgan: request.body.restore_faces,
cfg_scale: request.body.scale,
steps: request.body.steps,
width: request.body.width,
height: request.body.height,
karras: Boolean(request.body.karras),
n: 1,
prompt: `${request.body.prompt_prefix} ${request.body.prompt} ### ${request.body.negative_prompt}`,
params:
{
sampler_name: request.body.sampler,
hires_fix: request.body.enable_hr,
use_gfpgan: request.body.restore_faces,
cfg_scale: request.body.scale,
steps: request.body.steps,
width: request.body.width,
height: request.body.height,
karras: Boolean(request.body.karras),
n: 1,
},
r2: false,
nsfw: request.body.nfsw,
models: [request.body.model],
},
r2: false,
nsfw: request.body.nfsw,
models: [request.body.model],
},
{ token: api_key_horde });
{ token: api_key_horde });
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
await delay(CHECK_INTERVAL);
const check = await ai_horde.getImageGenerationCheck(generation.id);
console.log(check);
if (check.done) {
const result = await ai_horde.getImageGenerationStatus(generation.id);
return response.send(result.generations[0].img);
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
await delay(CHECK_INTERVAL);
const check = await ai_horde.getImageGenerationCheck(generation.id);
console.log(check);
if (check.done) {
const result = await ai_horde.getImageGenerationStatus(generation.id);
return response.send(result.generations[0].img);
}
/*
if (!check.is_possible) {
return response.sendStatus(503);
}
*/
if (check.faulted) {
return response.sendStatus(500);
}
}
/*
if (!check.is_possible) {
return response.sendStatus(503);
}
*/
if (check.faulted) {
return response.sendStatus(500);
}
return response.sendStatus(504);
} catch (error) {
console.error(error);
return response.sendStatus(500);
}
return response.sendStatus(504);
});
function writeSecret(key, value) {
@ -2991,4 +3013,4 @@ function readSecret(key) {
const fileContents = fs.readFileSync(SECRETS_FILE);
const secrets = JSON.parse(fileContents);
return secrets[key];
}
}