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
26722672 quietName: quietName,
26732673 };
26742674 originalResponseLength = responseLengthCustomized ? saveResponseLength(main_api, responseLength) : -1;
26752675 const generateFinished =return await Generate('quiet', options);
2676- return generateFinished;
26772676 } finally {
26782677 if (responseLengthCustomized) {
26792678 restoreResponseLength(main_api, originalResponseLength);
@@ -3328,9 +3327,9 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
33283327
33293328 let data = {};
33303329
33313330 if (api === 'koboldhorde') {
33323331 data = await generateHorde(prompt, generateData, abortController.signal, false);
33333332 } else if (api === 'openai') {
33343333 data = await sendOpenAIRequest('quiet', generateData, abortController.signal);
33353334 } else {
33363335 const generateUrl = getGenerateUrl(api);
@@ -3343,13 +3342,15 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
33433342 });
33443343
33453344 if (!response.ok) {
33463345 const error =throw await response.json();
3347- throw error;
33483346 }
33493347
33503348 data = await response.json();
33513349 }
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
33533354 if (data.error) {
33543355 throw new Error(data.response);
33553356 }
@@ -4401,6 +4402,11 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
44014402 return Promise.resolve();
44024403 }
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+ */
44044410 async function finishGenerating() {
44054411 if (power_user.console_log_prompts) {
44064412 console.log(generate_data.prompt);
@@ -4512,6 +4518,12 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
45124518
45134519 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+ */
45154527 async function onSuccess(data) {
45164528 if (!data) return;
45174529
@@ -4521,6 +4533,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
45214533
45224534 let messageChunk = '';
45234535
4536+ // if an error was returned in data (textgenwebui), show it and throw it
45244537 if (data.error) {
45254538 unblockGeneration(type);
45264539 generatedPromptCache = '';
@@ -4635,9 +4648,15 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
46354648 return Object.defineProperty(new String(getMessage), 'messageChunk', { value: messageChunk });
46364649 }
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+ */
46384656 function onError(exception) {
4657+ // if the response JSON was thrown (novel|textgenerationwebui|kobold), show the error message
46394658 if (typeof exception?.error?.message === 'string') {
46404659 toastr.error(exception.error.message, t`ErrorText generation error`, { timeOut: 10000, extendedTimeOut: 20000 });
46414660 }
46424661
46434662 generatedPromptCache = '';
@@ -5305,6 +5324,7 @@ function setInContextMessages(lastmsg, type) {
53055324 * @param {string} type Generation type
53065325 * @param {object} data Generation data
53075326 * @returns {Promise<object>} Response data from the API
5327+ * @throws {Error|object}
53085328 */
53095329export async function sendGenerationRequest(type, data) {
53105330 if (main_api === 'openai') {
@@ -5324,12 +5344,10 @@ export async function sendGenerationRequest(type, data) {
53245344 });
53255345
53265346 if (!response.ok) {
53275347 const error =throw await response.json();
5328- throw error;
53295348 }
53305349
53315350 const responseData =return await response.json();
5332- return responseData;
53335351}
53345352
53355353/**
@@ -5361,6 +5379,7 @@ export async function sendStreamingRequest(type, data) {
53615379 * Gets the generation endpoint URL for the specified API.
53625380 * @param {string} api API name
53635381 * @returns {string} Generation URL
5382+ * @throws {Error} If the API is unknown
53645383 */
53655384function getGenerateUrl(api) {
53665385 switch (api) {
public/scripts/extensions/stable-diffusion/index.js+8 -4
@@ -2362,6 +2362,7 @@ function ensureSelectionExists(setting, selector) {
23622362 * @param {string} [message] Chat message
23632363 * @param {function} [callback] Callback function
23642364 * @returns {Promise<string>} Image path
2365+ * @throws {Error} If the prompt or image generation fails
23652366 */
23662367async function generatePicture(initiator, args, trigger, message, callback) {
23672368 if (!trigger || trigger.trim().length === 0) {
@@ -2379,7 +2380,7 @@ async function generatePicture(initiator, args, trigger, message, callback) {
23792380
23802381 trigger = trigger.trim();
23812382 const generationType = getGenerationType(trigger);
23822383 console.log('GenerationImage generation mode', generationType, 'triggered with', trigger);
23832384 const quietPrompt = getQuietPrompt(generationType, trigger);
23842385 const context = getContext();
23852386
@@ -2387,7 +2388,7 @@ async function generatePicture(initiator, args, trigger, message, callback) {
23872388 ? context.groups[Object.keys(context.groups).filter(x => context.groups[x].id === context.groupId)[0]]?.id?.toString()
23882389 : context.characters[context.characterId]?.name;
23892390
23902391 if (generationType === generationMode.BACKGROUND) {
23912392 const callbackOriginal = callback;
23922393 callback = async function (prompt, imagePath, generationType, _negativePromptPrefix, _initiator, prefixedPrompt) {
23932394 const imgUrl = `url("${encodeURI(imagePath)}")`;
@@ -2415,6 +2416,8 @@ async function generatePicture(initiator, args, trigger, message, callback) {
24152416
24162417 try {
24172418 const combineNegatives = (prefix) => { negativePromptPrefix = combinePrefixes(negativePromptPrefix, prefix); };
2419+
2420+ // generate the text prompt for the image
24182421 const prompt = await getPrompt(generationType, message, trigger, quietPrompt, combineNegatives);
24192422 console.log('Processed image prompt:', prompt);
24202423
@@ -2425,6 +2428,7 @@ async function generatePicture(initiator, args, trigger, message, callback) {
24252428 args._abortController.addEventListener('abort', stopListener);
24262429 }
24272430
2431+ // generate the image
24282432 imagePath = await sendGenerationRequest(generationType, prompt, negativePromptPrefix, characterName, callback, initiator, abortController.signal);
24292433 } catch (err) {
24302434 console.trace(err);
@@ -2500,7 +2504,7 @@ function restoreOriginalDimensions(savedParams) {
25002504 */
25012505async function getPrompt(generationType, message, trigger, quietPrompt, combineNegatives) {
25022506 let prompt;
2503-
2507+ console.log('getPrompt: Generation mode', generationType, 'triggered with', trigger);
25042508 switch (generationType) {
25052509 case generationMode.RAW_LAST:
25062510 prompt = message || getRawLastMessage();
@@ -2718,7 +2722,7 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP
27182722 throw new Error('Endpoint did not return image data.');
27192723 }
27202724 } catch (err) {
27212725 console.error('Image generation request error: ', err);
27222726 toastr.error('Image generation failed. Please try again.' + '\n\n' + String(err), 'Image Generation');
27232727 return;
27242728 }
public/scripts/horde.js+8 -0
@@ -181,6 +181,14 @@ function setContextSizePreview() {
181181 }
182182}
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+ */
184192async function generateHorde(prompt, params, signal, reportProgress) {
185193 validateHordeModel();
186194 delete params.prompt;
public/scripts/openai.js+27 -1
@@ -1312,6 +1312,11 @@ export async function prepareOpenAIMessages({
13121312 return [chat, promptManager.tokenHandler.counts];
13131313}
13141314
1315+/**
1316+ * Handles errors during streaming requests.
1317+ * @param {Response} response
1318+ * @param {string} decoded - response text or decoded stream data
1319+ */
13151320function tryParseStreamingError(response, decoded) {
13161321 try {
13171322 const data = JSON.parse(decoded);
@@ -1320,9 +1325,12 @@ function tryParseStreamingError(response, decoded) {
13201325 return;
13211326 }
13221327
13231328 void checkQuotaError(data);
13241329 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+
13261334 if (data.error) {
13271335 toastr.error(data.error.message || response.statusText, 'Chat Completion API');
13281336 throw new Error(data);
@@ -1338,6 +1346,12 @@ function tryParseStreamingError(response, decoded) {
13381346 }
13391347}
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+ */
13411355async function checkQuotaError(data) {
13421356 const errorText = await renderTemplateAsync('quotaError');
13431357
@@ -1347,6 +1361,9 @@ async function checkQuotaError(data) {
13471361
13481362 if (data.quota_error) {
13491363 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
13501367 throw new Error(data);
13511368 }
13521369}
@@ -1765,6 +1782,15 @@ async function sendAltScaleRequest(messages, logit_bias, signal, type) {
17651782 return data.output;
17661783}
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+
17681794async function sendOpenAIRequest(type, messages, signal) {
17691795 // Provide default abort signal
17701796 if (!signal) {
public/scripts/textgen-settings.js+8 -0
@@ -880,6 +880,13 @@ function setSettingByName(setting, value, trigger) {
880880 }
881881}
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+ */
883890async function generateTextGenWithStreaming(generate_data, signal) {
884891 generate_data.stream = true;
885892
@@ -995,6 +1002,7 @@ export function parseTabbyLogprobs(data) {
9951002 * @param {Response} response - Response from the server.
9961003 * @param {string} decoded - Decoded response body.
9971004 * @returns {void} Nothing.
1005+ * @throws {Error} If the response contains an error message, throws Error with the message.
9981006 */
9991007function tryParseStreamingError(response, decoded) {
10001008 let data = {};