Stop any generation request (WIP)

This commit is contained in:
SillyLossy
2023-05-24 00:09:49 +03:00
parent 4feebd0ba1
commit f2f459cc55
6 changed files with 150 additions and 177 deletions

15
package-lock.json generated
View File

@ -27,6 +27,7 @@
"json5": "^2.2.3", "json5": "^2.2.3",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"node-fetch": "^2.6.11",
"node-rest-client": "^3.1.1", "node-rest-client": "^3.1.1",
"open": "^8.4.0", "open": "^8.4.0",
"piexifjs": "^1.0.6", "piexifjs": "^1.0.6",
@ -2055,8 +2056,9 @@
} }
}, },
"node_modules/node-fetch": { "node_modules/node-fetch": {
"version": "2.6.9", "version": "2.6.11",
"license": "MIT", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz",
"integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==",
"dependencies": { "dependencies": {
"whatwg-url": "^5.0.0" "whatwg-url": "^5.0.0"
}, },
@ -3092,7 +3094,8 @@
}, },
"node_modules/tr46": { "node_modules/tr46": {
"version": "0.0.3", "version": "0.0.3",
"license": "MIT" "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
}, },
"node_modules/truncate-utf8-bytes": { "node_modules/truncate-utf8-bytes": {
"version": "1.0.2", "version": "1.0.2",
@ -3180,7 +3183,8 @@
}, },
"node_modules/webidl-conversions": { "node_modules/webidl-conversions": {
"version": "3.0.1", "version": "3.0.1",
"license": "BSD-2-Clause" "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
}, },
"node_modules/webp-converter": { "node_modules/webp-converter": {
"version": "2.3.2", "version": "2.3.2",
@ -3192,7 +3196,8 @@
}, },
"node_modules/whatwg-url": { "node_modules/whatwg-url": {
"version": "5.0.0", "version": "5.0.0",
"license": "MIT", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": { "dependencies": {
"tr46": "~0.0.3", "tr46": "~0.0.3",
"webidl-conversions": "^3.0.0" "webidl-conversions": "^3.0.0"

View File

@ -18,6 +18,7 @@
"json5": "^2.2.3", "json5": "^2.2.3",
"mime-types": "^2.1.35", "mime-types": "^2.1.35",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
"node-fetch": "^2.6.11",
"node-rest-client": "^3.1.1", "node-rest-client": "^3.1.1",
"open": "^8.4.0", "open": "^8.4.0",
"piexifjs": "^1.0.6", "piexifjs": "^1.0.6",

View File

@ -2494,9 +2494,6 @@
</div> </div>
<div class="mes_bias"></div> <div class="mes_bias"></div>
</div> </div>
<div title="Stop Streaming" class="mes_stop">
<i class="fa-xl fa-solid fa-circle-stop"></i>
</div>
<div class="swipe_right fa-solid fa-chevron-right"> <div class="swipe_right fa-solid fa-chevron-right">
<div class="swipes-counter"></div> <div class="swipes-counter"></div>
</div> </div>
@ -2580,8 +2577,8 @@
<div id="options_button" class="fa-solid fa-bars"></div> <div id="options_button" class="fa-solid fa-bars"></div>
<textarea id="send_textarea" placeholder="Not connected to API!" name="text"></textarea> <textarea id="send_textarea" placeholder="Not connected to API!" name="text"></textarea>
<div id="send_but_sheld"> <div id="send_but_sheld">
<div id="loading_mes"> <div id="mes_stop" title="Abort request" class="mes_stop">
<div title="Loading" class="fa-solid fa-hourglass-half"></div> <i class="fa-solid fa-circle-stop"></i>
</div> </div>
<div id="send_but" class="fa-solid fa-paper-plane" title="Send a message"></div> <div id="send_but" class="fa-solid fa-paper-plane" title="Send a message"></div>
</div> </div>

View File

@ -587,6 +587,7 @@ var main_api;// = "kobold";
let novel_tier; let novel_tier;
let novelai_settings; let novelai_settings;
let novelai_setting_names; let novelai_setting_names;
let abortController;
//css //css
var css_mes_bg = $('<div class="mes"></div>').css("background"); var css_mes_bg = $('<div class="mes"></div>').css("background");
@ -1499,22 +1500,30 @@ function isStreamingEnabled() {
&& !isMultigenEnabled(); // Multigen has a quasi-streaming mode which breaks the real streaming && !isMultigenEnabled(); // Multigen has a quasi-streaming mode which breaks the real streaming
} }
function showStopButton() {
$('#mes_stop').css({ 'display': 'flex' });
}
function hideStopButton() {
$('#mes_stop').css({ 'display': 'none' });
}
class StreamingProcessor { class StreamingProcessor {
showStopButton(messageId) { showMessageButtons(messageId) {
if (messageId == -1) { if (messageId == -1) {
return; return;
} }
$(`#chat .mes[mesid="${messageId}"] .mes_stop`).css({ 'display': 'block' }); showStopButton();
$(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': 'none' }); $(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': 'none' });
} }
hideStopButton(messageId) { hideMessageButtons(messageId) {
if (messageId == -1) { if (messageId == -1) {
return; return;
} }
$(`#chat .mes[mesid="${messageId}"] .mes_stop`).css({ 'display': 'none' }); hideStopButton();
$(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': 'flex' }); $(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': 'flex' });
} }
@ -1527,7 +1536,7 @@ class StreamingProcessor {
else { else {
saveReply(this.type, text); saveReply(this.type, text);
messageId = count_view_mes - 1; messageId = count_view_mes - 1;
this.showStopButton(messageId); this.showMessageButtons(messageId);
} }
hideSwipeButtons(); hideSwipeButtons();
@ -1595,7 +1604,7 @@ class StreamingProcessor {
} }
onFinishStreaming(messageId, text) { onFinishStreaming(messageId, text) {
this.hideStopButton(this.messageId); this.hideMessageButtons(this.messageId);
this.onProgressStreaming(messageId, text, true); this.onProgressStreaming(messageId, text, true);
addCopyToCodeBlocks($(`#chat .mes[mesid="${messageId}"]`)); addCopyToCodeBlocks($(`#chat .mes[mesid="${messageId}"]`));
saveChatConditional(); saveChatConditional();
@ -1641,7 +1650,7 @@ class StreamingProcessor {
} }
onErrorStreaming() { onErrorStreaming() {
this.hideStopButton(this.messageId); this.hideMessageButtons(this.messageId);
$("#send_textarea").removeAttr('disabled'); $("#send_textarea").removeAttr('disabled');
is_send_press = false; is_send_press = false;
activateSendButtons(); activateSendButtons();
@ -2203,12 +2212,15 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
let generate_url = getGenerateUrl(); let generate_url = getGenerateUrl();
console.log('rungenerate calling API'); console.log('rungenerate calling API');
abortController = new AbortController();
showStopButton();
if (main_api == 'openai') { if (main_api == 'openai') {
if (isStreamingEnabled() && type !== 'quiet') { if (isStreamingEnabled() && type !== 'quiet') {
streamingProcessor.generator = await sendOpenAIRequest(type, generate_data.prompt, streamingProcessor.abortController.signal); streamingProcessor.generator = await sendOpenAIRequest(type, generate_data.prompt, streamingProcessor.abortController.signal);
} }
else { else {
sendOpenAIRequest(type, generate_data.prompt).then(onSuccess).catch(onError); sendOpenAIRequest(type, generate_data.prompt, abortController.signal).then(onSuccess).catch(onError);
} }
} }
else if (main_api == 'kobold' && horde_settings.use_horde) { else if (main_api == 'kobold' && horde_settings.use_horde) {
@ -2219,24 +2231,31 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
streamingProcessor.generator = await generatePoe(type, finalPromt, streamingProcessor.abortController.signal); streamingProcessor.generator = await generatePoe(type, finalPromt, streamingProcessor.abortController.signal);
} }
else { else {
generatePoe(type, finalPromt).then(onSuccess).catch(onError); generatePoe(type, finalPromt, abortController.signal).then(onSuccess).catch(onError);
} }
} }
else if (main_api == 'textgenerationwebui' && isStreamingEnabled() && type !== 'quiet') { else if (main_api == 'textgenerationwebui' && isStreamingEnabled() && type !== 'quiet') {
streamingProcessor.generator = await generateTextGenWithStreaming(generate_data, streamingProcessor.abortController.signal); streamingProcessor.generator = await generateTextGenWithStreaming(generate_data, streamingProcessor.abortController.signal);
} }
else { else {
jQuery.ajax({ try {
type: 'POST', // const response = await fetch(generate_url, {
url: generate_url, // method: 'POST',
data: JSON.stringify(generate_data), headers: getRequestHeaders(),
beforeSend: () => { }, cache: 'no-cache',
cache: false, body: JSON.stringify(generate_data),
dataType: "json", signal: abortController.signal,
contentType: "application/json", });
success: onSuccess,
error: onError if (!response.ok) {
}); //end of "if not data error" throw new Error(response.status);
}
const data = await response.json();
onSuccess(data);
} catch (error) {
onError(error);
}
} }
//set array object for prompt token itemization of this message //set array object for prompt token itemization of this message
@ -2284,6 +2303,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
} }
function onSuccess(data) { function onSuccess(data) {
hideStopButton();
is_send_press = false; is_send_press = false;
if (!data.error) { if (!data.error) {
//const getData = await response.json(); //const getData = await response.json();
@ -2386,14 +2406,14 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
} }
}; };
function onError(jqXHR, exception) { function onError(exception) {
hideStopButton();
reject(exception); reject(exception);
$("#send_textarea").removeAttr('disabled'); $("#send_textarea").removeAttr('disabled');
is_send_press = false; is_send_press = false;
activateSendButtons(); activateSendButtons();
setGenerationProgress(0); setGenerationProgress(0);
console.log(exception); console.log(exception);
console.log(jqXHR);
}; };
} //rungenerate ends } //rungenerate ends
@ -3233,13 +3253,13 @@ export function isMultigenEnabled() {
function activateSendButtons() { function activateSendButtons() {
is_send_press = false; is_send_press = false;
$("#send_but").css("display", "flex"); $("#send_but").css("display", "flex");
$("#loading_mes").css("display", "none");
$("#send_textarea").attr("disabled", false); $("#send_textarea").attr("disabled", false);
hideStopButton();
} }
function deactivateSendButtons() { function deactivateSendButtons() {
$("#send_but").css("display", "none"); $("#send_but").css("display", "none");
$("#loading_mes").css("display", "flex"); showStopButton();
} }
function resetChatState() { function resetChatState() {
@ -6466,6 +6486,10 @@ $(document).ready(function () {
streamingProcessor.onStopStreaming(); streamingProcessor.onStopStreaming();
streamingProcessor = null; streamingProcessor = null;
} }
if (!isStreamingEnabled() && abortController) {
abortController.abort();
abortController = null;
}
}); });
$('.drawer-toggle').click(function () { $('.drawer-toggle').click(function () {

View File

@ -416,30 +416,34 @@ code {
overflow: hidden; overflow: hidden;
} }
#send_but {
#send_but_sheld>div {
width: 40px; width: 40px;
height: 40px; height: 40px;
margin: 0; margin: 0;
display: none;
outline: none; outline: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
transition: 0.3s; transition: 0.3s;
opacity: 0.7; opacity: 0.7;
order: 99999;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
#loading_mes { #options_button:hover,
#send_but_sheld>div:hover {
opacity: 1;
filter: brightness(1.2);
}
#send_but {
display: none; display: none;
width: 40px;
height: 40px;
margin: 0 auto;
order: 99999; order: 99999;
align-items: center; }
justify-content: center;
filter: brightness(0.7); .mes_stop {
display: none;
order: 99998;
} }
#options_button { #options_button {
@ -466,12 +470,6 @@ code {
font-weight: 400; font-weight: 400;
} }
#options_button:hover,
#send_but:hover {
opacity: 1;
filter: brightness(1.2);
}
#options { #options {
opacity: 0.0; opacity: 0.0;
display: none; display: none;
@ -2269,18 +2267,6 @@ input[type="range"]::-webkit-slider-thumb {
backdrop-filter: blur(var(--SmartThemeBlurStrength)); backdrop-filter: blur(var(--SmartThemeBlurStrength));
} }
.mes_stop {
display: none;
cursor: pointer;
transition: opacity 0.3s ease-in-out;
height: 20px;
width: 20px;
opacity: 0.5;
position: absolute;
right: 15px;
bottom: 15px
}
.mes_buttons { .mes_buttons {
height: 20px; height: 20px;
grid-row-start: 1; grid-row-start: 1;

176
server.js
View File

@ -39,13 +39,11 @@ const multer = require("multer");
const http = require("http"); const http = require("http");
const https = require('https'); const https = require('https');
const basicAuthMiddleware = require('./src/middleware/basicAuthMiddleware'); const basicAuthMiddleware = require('./src/middleware/basicAuthMiddleware');
//const PNG = require('pngjs').PNG;
const extract = require('png-chunks-extract'); const extract = require('png-chunks-extract');
const encode = require('png-chunks-encode'); const encode = require('png-chunks-encode');
const PNGtext = require('png-chunk-text'); const PNGtext = require('png-chunk-text');
const jimp = require('jimp'); const jimp = require('jimp');
//const path = require('path');
const sanitize = require('sanitize-filename'); const sanitize = require('sanitize-filename');
const mime = require('mime-types'); const mime = require('mime-types');
@ -54,13 +52,11 @@ const crypto = require('crypto');
const ipaddr = require('ipaddr.js'); const ipaddr = require('ipaddr.js');
const json5 = require('json5'); const json5 = require('json5');
const ExifReader = require('exifreader');
const exif = require('piexifjs'); const exif = require('piexifjs');
const webp = require('webp-converter'); const webp = require('webp-converter');
const DeviceDetector = require("device-detector-js"); const DeviceDetector = require("device-detector-js");
const { TextEncoder, TextDecoder } = require('util'); const { TextEncoder, TextDecoder } = require('util');
const utf8Encode = new TextEncoder(); const utf8Encode = new TextEncoder();
const utf8Decode = new TextDecoder('utf-8', { ignoreBOM: true });
const commandExistsSync = require('command-exists').sync; const commandExistsSync = require('command-exists').sync;
const characterCardParser = require('./src/character-card-parser.js'); const characterCardParser = require('./src/character-card-parser.js');
@ -93,36 +89,25 @@ const ai_horde = new AIHorde({
}); });
const ipMatching = require('ip-matching'); const ipMatching = require('ip-matching');
var Client = require('node-rest-client').Client; const Client = require('node-rest-client').Client;
var client = new Client(); const client = new Client();
client.on('error', (err) => { client.on('error', (err) => {
console.error('An error occurred:', err); console.error('An error occurred:', err);
}); });
let poe = require('./poe-client'); const poe = require('./poe-client');
var api_server = "http://0.0.0.0:5000"; let api_server = "http://0.0.0.0:5000";
var api_novelai = "https://api.novelai.net"; let api_novelai = "https://api.novelai.net";
let api_openai = "https://api.openai.com/v1"; let api_openai = "https://api.openai.com/v1";
var main_api = "kobold"; let main_api = "kobold";
var response_get_story; let response_generate_novel;
var response_generate; let characters = {};
var response_generate_novel; let response_dw_bg;
var request_promt; let response_getstatus;
var response_promt;
var characters = {};
var character_i = 0;
var response_create;
var response_edit;
var response_dw_bg;
var response_getstatus;
var response_getstatus_novel;
var response_getlastversion;
let response_generate_openai;
let response_getstatus_openai;
//RossAscends: Added function to format dates used in files and chat timestamps to a humanized format. //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.
@ -220,7 +205,7 @@ const doubleCsrf = require('csrf-csrf').doubleCsrf;
const CSRF_SECRET = crypto.randomBytes(8).toString('hex'); const CSRF_SECRET = crypto.randomBytes(8).toString('hex');
const COOKIES_SECRET = crypto.randomBytes(8).toString('hex'); const COOKIES_SECRET = crypto.randomBytes(8).toString('hex');
const { invalidCsrfTokenError, generateToken, doubleCsrfProtection } = doubleCsrf({ const { generateToken, doubleCsrfProtection } = doubleCsrf({
getSecret: () => CSRF_SECRET, getSecret: () => CSRF_SECRET,
cookieName: "X-CSRF-Token", cookieName: "X-CSRF-Token",
cookieOptions: { cookieOptions: {
@ -342,27 +327,29 @@ app.get('/version', function (_, response) {
//**************Kobold api //**************Kobold api
app.post("/generate", jsonParser, async function (request, response_generate = response) { app.post("/generate", jsonParser, async function (request, response_generate = response) {
if (!request.body) return response_generate.sendStatus(400); if (!request.body) return response_generate.sendStatus(400);
//console.log(request.body.prompt);
//const dataJson = JSON.parse(request.body);
request_promt = request.body.prompt;
//console.log(request.body); const request_prompt = request.body.prompt;
var this_settings = { const controller = new AbortController();
prompt: request_promt, request.socket.removeAllListeners('close');
request.socket.on('close', function () {
console.log('Kobold aborted');
controller.abort();
});
let this_settings = {
prompt: request_prompt,
use_story: false, use_story: false,
use_memory: false, use_memory: false,
use_authors_note: false, use_authors_note: false,
use_world_info: false, use_world_info: false,
max_context_length: request.body.max_context_length, max_context_length: request.body.max_context_length,
singleline: !!request.body.singleline, singleline: !!request.body.singleline,
//temperature: request.body.temperature,
//max_length: request.body.max_length
}; };
if (request.body.gui_settings == false) { if (request.body.gui_settings == false) {
var sampler_order = [request.body.s1, request.body.s2, request.body.s3, request.body.s4, request.body.s5, request.body.s6, request.body.s7]; const sampler_order = [request.body.s1, request.body.s2, request.body.s3, request.body.s4, request.body.s5, request.body.s6, request.body.s7];
this_settings = { this_settings = {
prompt: request_promt, prompt: request_prompt,
use_story: false, use_story: false,
use_memory: false, use_memory: false,
use_authors_note: false, use_authors_note: false,
@ -387,9 +374,10 @@ app.post("/generate", jsonParser, async function (request, response_generate = r
} }
console.log(this_settings); console.log(this_settings);
var args = { const args = {
data: this_settings, body: JSON.stringify(this_settings),
headers: { "Content-Type": "application/json" } signal: controller.signal,
headers: { "Content-Type": "application/json" },
}; };
const MAX_RETRIES = 10; const MAX_RETRIES = 10;
@ -426,13 +414,15 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
console.log(request.body); console.log(request.body);
if (!!request.header('X-Response-Streaming')) { const controller = new AbortController();
let isStreamingStopped = false; let isGenerationStopped = false;
request.socket.removeAllListeners('close'); request.socket.removeAllListeners('close');
request.socket.on('close', function () { request.socket.on('close', function () {
isStreamingStopped = true; isGenerationStopped = true;
controller.abort();
}); });
if (request.header('X-Response-Streaming')) {
response_generate.writeHead(200, { response_generate.writeHead(200, {
'Content-Type': 'text/plain;charset=utf-8', 'Content-Type': 'text/plain;charset=utf-8',
'Transfer-Encoding': 'chunked', 'Transfer-Encoding': 'chunked',
@ -459,7 +449,7 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
}); });
while (true) { while (true) {
if (isStreamingStopped) { if (isGenerationStopped) {
console.error('Streaming stopped by user. Closing websocket...'); console.error('Streaming stopped by user. Closing websocket...');
websocket.close(); websocket.close();
return; return;
@ -504,29 +494,20 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
} }
} }
else { else {
var args = { const args = {
data: request.body, body: JSON.stringify(request.body),
headers: { "Content-Type": "application/json" } headers: { "Content-Type": "application/json" },
signal: controller.signal,
}; };
client.post(api_server + "/v1/generate", args, function (data, response) {
console.log("####", data); try {
if (response.statusCode == 200) { const data = await postAsync(api_server + "/v1/generate", args);
console.log(data); console.log(data);
response_generate.send(data); return response_generate.send(data);
} catch (error) {
console.log(error);
return response_generate.send({ error: true });
} }
if (response.statusCode == 422) {
console.log('Validation error');
response_generate.send({ error: true });
}
if (response.statusCode == 501 || response.statusCode == 503 || response.statusCode == 507) {
console.log(data);
response_generate.send({ error: true });
}
}).on('error', function (err) {
console.log(err);
//console.log('something went wrong on the request', err.request.options);
response_generate.send({ error: true });
});
} }
}); });
@ -610,7 +591,7 @@ app.post("/getstatus", jsonParser, async function (request, response_getstatus =
data.result = "no_connection"; data.result = "no_connection";
} }
response_getstatus.send(data); response_getstatus.send(data);
}).on('error', function (err) { }).on('error', function () {
response_getstatus.send({ result: "no_connection" }); response_getstatus.send({ result: "no_connection" });
}); });
}); });
@ -691,18 +672,6 @@ function tryParse(str) {
} }
} }
function checkServer() {
api_server = 'http://127.0.0.1:5000';
var args = {
headers: { "Content-Type": "application/json" }
};
client.get(api_server + "/v1/model", args, function (data, response) {
console.log(data.result);
console.log(data);
}).on('error', function (err) {
console.log(err);
});
}
//***************** Main functions //***************** Main functions
function charaFormatData(data) { function charaFormatData(data) {
@ -767,7 +736,6 @@ app.post("/renamecharacter", jsonParser, async function (request, response) {
const newAvatarName = `${newInternalName}.png`; const newAvatarName = `${newInternalName}.png`;
const oldAvatarPath = path.join(charactersPath, oldAvatarName); const oldAvatarPath = path.join(charactersPath, oldAvatarName);
const newAvatarPath = path.join(charactersPath, newAvatarName);
const oldChatsPath = path.join(chatsPath, oldInternalName); const oldChatsPath = path.join(chatsPath, oldInternalName);
const newChatsPath = path.join(chatsPath, newInternalName); const newChatsPath = path.join(chatsPath, newInternalName);
@ -1384,7 +1352,7 @@ app.post("/getstatus_novelai", jsonParser, function (request, response_getstatus
console.log(data); console.log(data);
response_getstatus_novel.send({ error: true }); response_getstatus_novel.send({ error: true });
} }
}).on('error', function (err) { }).on('error', function () {
//console.log(''); //console.log('');
//console.log('something went wrong on the request', err.request.options); //console.log('something went wrong on the request', err.request.options);
response_getstatus_novel.send({ error: true }); response_getstatus_novel.send({ error: true });
@ -1451,7 +1419,7 @@ app.post("/generate_novelai", jsonParser, function (request, response_generate_n
console.log(data); console.log(data);
response_generate_novel.send({ error: true }); response_generate_novel.send({ error: true });
} }
}).on('error', function (err) { }).on('error', function () {
//console.log(''); //console.log('');
//console.log('something went wrong on the request', err.request.options); //console.log('something went wrong on the request', err.request.options);
response_getstatus.send({ error: true }); response_getstatus.send({ error: true });
@ -2111,6 +2079,15 @@ app.post('/generate_poe', jsonParser, async (request, response) => {
return response.sendStatus(401); return response.sendStatus(401);
} }
let isGenerationStopped = false;
request.socket.removeAllListeners('close');
request.socket.on('close', function () {
isGenerationStopped = true;
if (client) {
client.abortController.abort();
}
});
const prompt = request.body.prompt; const prompt = request.body.prompt;
const bot = request.body.bot ?? POE_DEFAULT_BOT; const bot = request.body.bot ?? POE_DEFAULT_BOT;
const streaming = request.body.streaming ?? false; const streaming = request.body.streaming ?? false;
@ -2126,13 +2103,6 @@ app.post('/generate_poe', jsonParser, async (request, response) => {
} }
if (streaming) { if (streaming) {
let isStreamingStopped = false;
request.socket.removeAllListeners('close');
request.socket.on('close', function () {
isStreamingStopped = true;
client.abortController.abort();
});
try { try {
response.writeHead(200, { response.writeHead(200, {
'Content-Type': 'text/plain;charset=utf-8', 'Content-Type': 'text/plain;charset=utf-8',
@ -2142,7 +2112,7 @@ app.post('/generate_poe', jsonParser, async (request, response) => {
let reply = ''; let reply = '';
for await (const mes of client.send_message(bot, prompt)) { for await (const mes of client.send_message(bot, prompt)) {
if (isStreamingStopped) { if (isGenerationStopped) {
console.error('Streaming stopped by user. Closing websocket...'); console.error('Streaming stopped by user. Closing websocket...');
break; break;
} }
@ -2158,7 +2128,7 @@ app.post('/generate_poe', jsonParser, async (request, response) => {
} }
finally { finally {
client.disconnect_ws(); client.disconnect_ws();
return response.end(); response.end();
} }
} }
else { else {
@ -2390,7 +2360,7 @@ app.post("/getstatus_openai", jsonParser, function (request, response_getstatus_
console.log(data); console.log(data);
response_getstatus_openai.send({ error: true }); response_getstatus_openai.send({ error: true });
} }
}).on('error', function (err) { }).on('error', function () {
response_getstatus_openai.send({ error: true }); response_getstatus_openai.send({ error: true });
}); });
}); });
@ -2628,16 +2598,6 @@ app.post("/tokenize_llama", jsonParser, async function (request, response) {
}); });
// ** REST CLIENT ASYNC WRAPPERS ** // ** REST CLIENT ASYNC WRAPPERS **
function deleteAsync(url, args) {
return new Promise((resolve, reject) => {
client.delete(url, args, (data, response) => {
if (response.statusCode >= 400) {
reject(data);
}
resolve(data);
}).on('error', e => reject(e));
})
}
function putAsync(url, args) { function putAsync(url, args) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -2650,15 +2610,15 @@ function putAsync(url, args) {
}) })
} }
function postAsync(url, args) { async function postAsync(url, args) {
return new Promise((resolve, reject) => { const response = await fetch(url, { method: 'POST', args });
client.post(url, args, (data, response) => {
if (response.statusCode >= 400) { if (response.ok) {
reject([data, response]); const data = response.json();
return data;
} }
resolve(data);
}).on('error', e => reject(e)); throw new Error(response.statusText);
})
} }
function getAsync(url, args) { function getAsync(url, args) {
@ -2876,7 +2836,7 @@ app.post('/generate_horde', jsonParser, async (request, response) => {
const url = 'https://horde.koboldai.net/api/v2/generate/text/async'; const url = 'https://horde.koboldai.net/api/v2/generate/text/async';
const args = { const args = {
data: request.body, body: JSON.stringify(request.body),
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Client-Agent": request.header('Client-Agent'), "Client-Agent": request.header('Client-Agent'),