Linting and commenting Linting and commenting Linting and commenting Linting and commenting Linting and commenting

0383ea52e98213ff73a74545acf4b182bf662781

ceruleandeep <deep@cerulean.navy>

5 files changed, +81 -16Ignore whitespace
public/script.js+30 -11
@@ -2672,8 +2672,7 @@ export async function generateQuietPrompt(quiet_prompt, quietToLoud, skipWIAN, q
2672 quietName: quietName,2672 quietName: quietName,
2673 };2673 };
2674 originalResponseLength = responseLengthCustomized ? saveResponseLength(main_api, responseLength) : -1;2674 originalResponseLength = responseLengthCustomized ? saveResponseLength(main_api, responseLength) : -1;
2675 const generateFinished = await Generate('quiet', options);2675 return await Generate('quiet', options);
2676 return generateFinished;
2677 } finally {2676 } finally {
2678 if (responseLengthCustomized) {2677 if (responseLengthCustomized) {
2679 restoreResponseLength(main_api, originalResponseLength);2678 restoreResponseLength(main_api, originalResponseLength);
@@ -3328,9 +3327,9 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
33283327
3329 let data = {};3328 let data = {};
33303329
3331 if (api == 'koboldhorde') {3330 if (api === 'koboldhorde') {
3332 data = await generateHorde(prompt, generateData, abortController.signal, false);3331 data = await generateHorde(prompt, generateData, abortController.signal, false);
3333 } else if (api == 'openai') {3332 } else if (api === 'openai') {
3334 data = await sendOpenAIRequest('quiet', generateData, abortController.signal);3333 data = await sendOpenAIRequest('quiet', generateData, abortController.signal);
3335 } else {3334 } else {
3336 const generateUrl = getGenerateUrl(api);3335 const generateUrl = getGenerateUrl(api);
@@ -3343,13 +3342,15 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
3343 });3342 });
33443343
3345 if (!response.ok) {3344 if (!response.ok) {
3346 const error = await response.json();3345 throw await response.json();
3347 throw error;
3348 }3346 }
33493347
3350 data = await response.json();3348 data = await response.json();
3351 }3349 }
33523350
3351 // should only happen for text completions
3352 // other frontend paths do not return data if calling the backend fails,
3353 // they throw things instead
3353 if (data.error) {3354 if (data.error) {
3354 throw new Error(data.response);3355 throw new Error(data.response);
3355 }3356 }
@@ -4401,6 +4402,11 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
4401 return Promise.resolve();4402 return Promise.resolve();
4402 }4403 }
44034404
4405 /**
4406 * Saves itemized prompt bits and calls streaming or non-streaming generation API.
4407 * @returns {Promise<void|*|Awaited<*>|String|{fromStream}|string|undefined|Object>}
4408 * @throws {Error|object} Error with message text, or Error with response JSON (OAI/Horde), or the actual response JSON (novel|textgenerationwebui|kobold)
4409 */
4404 async function finishGenerating() {4410 async function finishGenerating() {
4405 if (power_user.console_log_prompts) {4411 if (power_user.console_log_prompts) {
4406 console.log(generate_data.prompt);4412 console.log(generate_data.prompt);
@@ -4512,6 +4518,12 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
45124518
4513 return finishGenerating().then(onSuccess, onError);4519 return finishGenerating().then(onSuccess, onError);
45144520
4521 /**
4522 * Handles the successful response from the generation API.
4523 * @param data
4524 * @returns {Promise<String|{fromStream}|*|string|string|void|Awaited<*>|undefined>}
4525 * @throws {Error} Throws an error if the response data contains an error message
4526 */
4515 async function onSuccess(data) {4527 async function onSuccess(data) {
4516 if (!data) return;4528 if (!data) return;
45174529
@@ -4521,6 +4533,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
45214533
4522 let messageChunk = '';4534 let messageChunk = '';
45234535
4536 // if an error was returned in data (textgenwebui), show it and throw it
4524 if (data.error) {4537 if (data.error) {
4525 unblockGeneration(type);4538 unblockGeneration(type);
4526 generatedPromptCache = '';4539 generatedPromptCache = '';
@@ -4635,9 +4648,15 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
4635 return Object.defineProperty(new String(getMessage), 'messageChunk', { value: messageChunk });4648 return Object.defineProperty(new String(getMessage), 'messageChunk', { value: messageChunk });
4636 }4649 }
46374650
4651 /**
4652 * Exception handler for finishGenerating
4653 * @param {Error|object} exception Error or response JSON
4654 * @throws {Error|object} Re-throws the exception
4655 */
4638 function onError(exception) {4656 function onError(exception) {
4657 // if the response JSON was thrown (novel|textgenerationwebui|kobold), show the error message
4639 if (typeof exception?.error?.message === 'string') {4658 if (typeof exception?.error?.message === 'string') {
4640 toastr.error(exception.error.message, t`Error`, { timeOut: 10000, extendedTimeOut: 20000 });4659 toastr.error(exception.error.message, t`Text generation error`, { timeOut: 10000, extendedTimeOut: 20000 });
4641 }4660 }
46424661
4643 generatedPromptCache = '';4662 generatedPromptCache = '';
@@ -5305,6 +5324,7 @@ function setInContextMessages(lastmsg, type) {
5305 * @param {string} type Generation type5324 * @param {string} type Generation type
5306 * @param {object} data Generation data5325 * @param {object} data Generation data
5307 * @returns {Promise<object>} Response data from the API5326 * @returns {Promise<object>} Response data from the API
5327 * @throws {Error|object}
5308 */5328 */
5309export async function sendGenerationRequest(type, data) {5329export async function sendGenerationRequest(type, data) {
5310 if (main_api === 'openai') {5330 if (main_api === 'openai') {
@@ -5324,12 +5344,10 @@ export async function sendGenerationRequest(type, data) {
5324 });5344 });
53255345
5326 if (!response.ok) {5346 if (!response.ok) {
5327 const error = await response.json();5347 throw await response.json();
5328 throw error;
5329 }5348 }
53305349
5331 const responseData = await response.json();5350 return await response.json();
5332 return responseData;
5333}5351}
53345352
5335/**5353/**
@@ -5361,6 +5379,7 @@ export async function sendStreamingRequest(type, data) {
5361 * Gets the generation endpoint URL for the specified API.5379 * Gets the generation endpoint URL for the specified API.
5362 * @param {string} api API name5380 * @param {string} api API name
5363 * @returns {string} Generation URL5381 * @returns {string} Generation URL
5382 * @throws {Error} If the API is unknown
5364 */5383 */
5365function getGenerateUrl(api) {5384function getGenerateUrl(api) {
5366 switch (api) {5385 switch (api) {
public/scripts/extensions/stable-diffusion/index.js+8 -4
@@ -2362,6 +2362,7 @@ function ensureSelectionExists(setting, selector) {
2362 * @param {string} [message] Chat message2362 * @param {string} [message] Chat message
2363 * @param {function} [callback] Callback function2363 * @param {function} [callback] Callback function
2364 * @returns {Promise<string>} Image path2364 * @returns {Promise<string>} Image path
2365 * @throws {Error} If the prompt or image generation fails
2365 */2366 */
2366async function generatePicture(initiator, args, trigger, message, callback) {2367async function generatePicture(initiator, args, trigger, message, callback) {
2367 if (!trigger || trigger.trim().length === 0) {2368 if (!trigger || trigger.trim().length === 0) {
@@ -2379,7 +2380,7 @@ async function generatePicture(initiator, args, trigger, message, callback) {
23792380
2380 trigger = trigger.trim();2381 trigger = trigger.trim();
2381 const generationType = getGenerationType(trigger);2382 const generationType = getGenerationType(trigger);
2382 console.log('Generation mode', generationType, 'triggered with', trigger);2383 console.log('Image generation mode', generationType, 'triggered with', trigger);
2383 const quietPrompt = getQuietPrompt(generationType, trigger);2384 const quietPrompt = getQuietPrompt(generationType, trigger);
2384 const context = getContext();2385 const context = getContext();
23852386
@@ -2387,7 +2388,7 @@ async function generatePicture(initiator, args, trigger, message, callback) {
2387 ? context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString()2388 ? context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString()
2388 : context.characters[context.characterId]?.name;2389 : context.characters[context.characterId]?.name;
23892390
2390 if (generationType == generationMode.BACKGROUND) {2391 if (generationType === generationMode.BACKGROUND) {
2391 const callbackOriginal = callback;2392 const callbackOriginal = callback;
2392 callback = async function (prompt, imagePath, generationType, _negativePromptPrefix, _initiator, prefixedPrompt) {2393 callback = async function (prompt, imagePath, generationType, _negativePromptPrefix, _initiator, prefixedPrompt) {
2393 const imgUrl = `url("${encodeURI(imagePath)}")`;2394 const imgUrl = `url("${encodeURI(imagePath)}")`;
@@ -2415,6 +2416,8 @@ async function generatePicture(initiator, args, trigger, message, callback) {
24152416
2416 try {2417 try {
2417 const combineNegatives = (prefix) => { negativePromptPrefix = combinePrefixes(negativePromptPrefix, prefix); };2418 const combineNegatives = (prefix) => { negativePromptPrefix = combinePrefixes(negativePromptPrefix, prefix); };
2419
2420 // generate the text prompt for the image
2418 const prompt = await getPrompt(generationType, message, trigger, quietPrompt, combineNegatives);2421 const prompt = await getPrompt(generationType, message, trigger, quietPrompt, combineNegatives);
2419 console.log('Processed image prompt:', prompt);2422 console.log('Processed image prompt:', prompt);
24202423
@@ -2425,6 +2428,7 @@ async function generatePicture(initiator, args, trigger, message, callback) {
2425 args._abortController.addEventListener('abort', stopListener);2428 args._abortController.addEventListener('abort', stopListener);
2426 }2429 }
24272430
2431 // generate the image
2428 imagePath = await sendGenerationRequest(generationType, prompt, negativePromptPrefix, characterName, callback, initiator, abortController.signal);2432 imagePath = await sendGenerationRequest(generationType, prompt, negativePromptPrefix, characterName, callback, initiator, abortController.signal);
2429 } catch (err) {2433 } catch (err) {
2430 console.trace(err);2434 console.trace(err);
@@ -2500,7 +2504,7 @@ function restoreOriginalDimensions(savedParams) {
2500 */2504 */
2501async function getPrompt(generationType, message, trigger, quietPrompt, combineNegatives) {2505async function getPrompt(generationType, message, trigger, quietPrompt, combineNegatives) {
2502 let prompt;2506 let prompt;
25032507 console.log('getPrompt: Generation mode', generationType, 'triggered with', trigger);
2504 switch (generationType) {2508 switch (generationType) {
2505 case generationMode.RAW_LAST:2509 case generationMode.RAW_LAST:
2506 prompt = message || getRawLastMessage();2510 prompt = message || getRawLastMessage();
@@ -2718,7 +2722,7 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP
2718 throw new Error('Endpoint did not return image data.');2722 throw new Error('Endpoint did not return image data.');
2719 }2723 }
2720 } catch (err) {2724 } catch (err) {
2721 console.error(err);2725 console.error('Image generation request error: ', err);
2722 toastr.error('Image generation failed. Please try again.' + '\n\n' + String(err), 'Image Generation');2726 toastr.error('Image generation failed. Please try again.' + '\n\n' + String(err), 'Image Generation');
2723 return;2727 return;
2724 }2728 }
public/scripts/horde.js+8 -0
@@ -181,6 +181,14 @@ function setContextSizePreview() {
181 }181 }
182}182}
183183
184/** Generates text using the Horde API.
185 * @param {string} prompt
186 * @param params
187 * @param signal
188 * @param reportProgress
189 * @returns {Promise<{text: *, workerName: string}>}
190 * @throws {Error}
191 */
184async function generateHorde(prompt, params, signal, reportProgress) {192async function generateHorde(prompt, params, signal, reportProgress) {
185 validateHordeModel();193 validateHordeModel();
186 delete params.prompt;194 delete params.prompt;
public/scripts/openai.js+27 -1
@@ -1312,6 +1312,11 @@ export async function prepareOpenAIMessages({
1312 return [chat, promptManager.tokenHandler.counts];1312 return [chat, promptManager.tokenHandler.counts];
1313}1313}
13141314
1315/**
1316 * Handles errors during streaming requests.
1317 * @param {Response} response
1318 * @param {string} decoded - response text or decoded stream data
1319 */
1315function tryParseStreamingError(response, decoded) {1320function tryParseStreamingError(response, decoded) {
1316 try {1321 try {
1317 const data = JSON.parse(decoded);1322 const data = JSON.parse(decoded);
@@ -1320,9 +1325,12 @@ function tryParseStreamingError(response, decoded) {
1320 return;1325 return;
1321 }1326 }
13221327
1323 checkQuotaError(data);1328 void checkQuotaError(data);
1324 checkModerationError(data);1329 checkModerationError(data);
13251330
1331 // these do not throw correctly (equiv to Error("[object Object]"))
1332 // if trying to fix "[object Object]" displayed to users, start here
1333
1326 if (data.error) {1334 if (data.error) {
1327 toastr.error(data.error.message || response.statusText, 'Chat Completion API');1335 toastr.error(data.error.message || response.statusText, 'Chat Completion API');
1328 throw new Error(data);1336 throw new Error(data);
@@ -1338,6 +1346,12 @@ function tryParseStreamingError(response, decoded) {
1338 }1346 }
1339}1347}
13401348
1349/**
1350 * Checks if the response contains a quota error and displays a popup if it does.
1351 * @param data
1352 * @returns {Promise<void>}
1353 * @throws {object} - response JSON
1354 */
1341async function checkQuotaError(data) {1355async function checkQuotaError(data) {
1342 const errorText = await renderTemplateAsync('quotaError');1356 const errorText = await renderTemplateAsync('quotaError');
13431357
@@ -1347,6 +1361,9 @@ async function checkQuotaError(data) {
13471361
1348 if (data.quota_error) {1362 if (data.quota_error) {
1349 callPopup(errorText, 'text');1363 callPopup(errorText, 'text');
1364
1365 // this does not throw correctly (equiv to Error("[object Object]"))
1366 // if trying to fix "[object Object]" displayed to users, start here
1350 throw new Error(data);1367 throw new Error(data);
1351 }1368 }
1352}1369}
@@ -1765,6 +1782,15 @@ async function sendAltScaleRequest(messages, logit_bias, signal, type) {
1765 return data.output;1782 return data.output;
1766}1783}
17671784
1785/**
1786 * Send a chat completion request to backend
1787 * @param {string} type (impersonate, quiet, continue, etc)
1788 * @param {Array} messages
1789 * @param {AbortSignal?} signal
1790 * @returns {Promise<unknown>}
1791 * @throws {Error}
1792 */
1793
1768async function sendOpenAIRequest(type, messages, signal) {1794async function sendOpenAIRequest(type, messages, signal) {
1769 // Provide default abort signal1795 // Provide default abort signal
1770 if (!signal) {1796 if (!signal) {
public/scripts/textgen-settings.js+8 -0
@@ -880,6 +880,13 @@ function setSettingByName(setting, value, trigger) {
880 }880 }
881}881}
882882
883/**
884 * Sends a streaming request for textgenerationwebui.
885 * @param generate_data
886 * @param signal
887 * @returns {Promise<(function(): AsyncGenerator<{swipes: [], text: string, toolCalls: [], logprobs: {token: string, topLogprobs: Candidate[]}|null}, void, *>)|*>}
888 * @throws {Error} - If the response status is not OK, or from within the generator
889 */
883async function generateTextGenWithStreaming(generate_data, signal) {890async function generateTextGenWithStreaming(generate_data, signal) {
884 generate_data.stream = true;891 generate_data.stream = true;
885892
@@ -995,6 +1002,7 @@ export function parseTabbyLogprobs(data) {
995 * @param {Response} response - Response from the server.1002 * @param {Response} response - Response from the server.
996 * @param {string} decoded - Decoded response body.1003 * @param {string} decoded - Decoded response body.
997 * @returns {void} Nothing.1004 * @returns {void} Nothing.
1005 * @throws {Error} If the response contains an error message, throws Error with the message.
998 */1006 */
999function tryParseStreamingError(response, decoded) {1007function tryParseStreamingError(response, decoded) {
1000 let data = {};1008 let data = {};