Refactor generateRaw/generateQuietPrompt calls (#4277) * generateQuietPrompt: Update to object arguments * generateRaw: Update to object arguments * Fix jsdoc * Fix lint * Unwrap JSON schema options * Remove default args from gen call

1a921576430e1e0d63b3ef4efe8d6f4e9d544cf4

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
7 files changed, +89 -47Showing whitespace changes
public/script.js+45 -32
@@ -2330,37 +2330,43 @@ export function getStoppingStrings(isImpersonate, isContinue) {
23302330
2331/**2331/**
2332 * Background generation based on the provided prompt.2332 * Background generation based on the provided prompt.
2333 * @param {string} quietPrompt Instruction prompt for the AI2333 * @typedef {object} GenerateQuietPromptParams
2334 * @param {boolean} [quietToLoud] Whether the message should be sent in a foreground (loud) or background (quiet) mode2334 * @prop {string} [quietPrompt] Instruction prompt for the AI
2335 * @param {boolean} [skipWIAN] Whether to skip addition of World Info and Author's Note into the prompt2335 * @prop {boolean} [quietToLoud] Whether the message should be sent in a foreground (loud) or background (quiet) mode
2336 * @param {string} [quietImage] Image to use for the quiet prompt2336 * @prop {boolean} [skipWIAN] Whether to skip addition of World Info and Author's Note into the prompt
2337 * @param {string} [quietName] Name to use for the quiet prompt (defaults to "System:")2337 * @prop {string} [quietImage] Image to use for the quiet prompt
2338 * @param {number} [responseLength] Maximum response length. If unset, the global default value is used.2338 * @prop {string} [quietName] Name to use for the quiet prompt (defaults to "System:")
2339 * @param {number} [forceChId] Character ID to use for this generation run. Works in groups only.2339 * @prop {number} [responseLength] Maximum response length. If unset, the global default value is used.
2340 * @param {AdditionalRequestOptions} [options={}] Additional generation request options.2340 * @prop {number} [forceChId] Character ID to use for this generation run. Works in groups only.
2341 * @prop {object} [jsonSchema] JSON schema to use for the structured generation. Usually requires a special instruction.
2342 * @param {GenerateQuietPromptParams} params Parameters for the quiet prompt generation
2341 * @returns {Promise<string>} Generated text. If using structured output, will contain a serialized JSON object.2343 * @returns {Promise<string>} Generated text. If using structured output, will contain a serialized JSON object.
2342 */2344 */
2343export async function generateQuietPrompt(quietPrompt, quietToLoud = false, skipWIAN = false, quietImage = null, quietName = null, responseLength = null, forceChId = null, { jsonSchema } = {}) {2345export async function generateQuietPrompt({ quietPrompt = '', quietToLoud = false, skipWIAN = false, quietImage = null, quietName = null, responseLength = null, forceChId = null, jsonSchema = null } = {}) {
2344 console.log('got into genQuietPrompt');2346 if (arguments.length > 0 && typeof arguments[0] !== 'object') {
2347 console.trace('generateQuietPrompt called with positional arguments. Please use an object instead.');
2348 [quietPrompt, quietToLoud, skipWIAN, quietImage, quietName, responseLength, forceChId, jsonSchema] = arguments;
2349 }
2350
2345 const responseLengthCustomized = typeof responseLength === 'number' && responseLength > 0;2351 const responseLengthCustomized = typeof responseLength === 'number' && responseLength > 0;
2346 let eventHook = () => { };2352 let eventHook = () => { };
2347 try {2353 try {
2348 /** @type {GenerateOptions} */2354 /** @type {GenerateOptions} */
2349 const options = {2355 const generateOptions = {
2350 quiet_prompt: quietPrompt,2356 quiet_prompt: quietPrompt ?? '',
2351 quietToLoud,2357 quietToLoud: quietToLoud ?? false,
2352 skipWIAN: skipWIAN,2358 skipWIAN: skipWIAN ?? false,
2353 force_name2: true,2359 force_name2: true,
2354 quietImage: quietImage,2360 quietImage: quietImage ?? null,
2355 quietName: quietName,2361 quietName: quietName ?? null,
2356 force_chid: forceChId,2362 force_chid: forceChId ?? null,
2357 jsonSchema: jsonSchema,2363 jsonSchema: jsonSchema ?? null,
2358 };2364 };
2359 if (responseLengthCustomized) {2365 if (responseLengthCustomized) {
2360 TempResponseLength.save(main_api, responseLength);2366 TempResponseLength.save(main_api, responseLength);
2361 eventHook = TempResponseLength.setupEventHook(main_api);2367 eventHook = TempResponseLength.setupEventHook(main_api);
2362 }2368 }
2363 const result = await Generate('quiet', options);2369 const result = await Generate('quiet', generateOptions);
2364 return removeReasoningFromString(result);2370 return removeReasoningFromString(result);
2365 } finally {2371 } finally {
2366 if (responseLengthCustomized && TempResponseLength.isCustomized()) {2372 if (responseLengthCustomized && TempResponseLength.isCustomized()) {
@@ -3121,18 +3127,25 @@ export function createRawPrompt(prompt, api, instructOverride, quietToLoud, syst
3121/**3127/**
3122 * Generates a message using the provided prompt.3128 * Generates a message using the provided prompt.
3123 * If the prompt is an array of chat-style messages and not using chat completion, it will be converted to a text prompt.3129 * If the prompt is an array of chat-style messages and not using chat completion, it will be converted to a text prompt.
3124 * @param {string | object[]} prompt Prompt to generate a message from. Can be a string or an array of chat-style messages, i.e. [{role: '', content: ''}, ...]3130 * @typedef {object} GenerateRawParams
3125 * @param {string} api API to use. Main API is used if not specified.3131 * @prop {string | object[]} [prompt] Prompt to generate a message from. Can be a string or an array of chat-style messages, i.e. [{role: '', content: ''}, ...]
3126 * @param {boolean} instructOverride true to override instruct mode, false to use the default value3132 * @prop {string} [api] API to use. Main API is used if not specified.
3127 * @param {boolean} quietToLoud true to generate a message in system mode, false to generate a message in character mode3133 * @prop {boolean} [instructOverride] true to override instruct mode, false to use the default value
3128 * @param {string} [systemPrompt] System prompt to use.3134 * @prop {boolean} [quietToLoud] true to generate a message in system mode, false to generate a message in character mode
3129 * @param {number} [responseLength] Maximum response length. If unset, the global default value is used.3135 * @prop {string} [systemPrompt] System prompt to use.
3130 * @param {boolean} [trimNames] Whether to allow trimming "{{user}}:" and "{{char}}:" from the response.3136 * @prop {number} [responseLength] Maximum response length. If unset, the global default value is used.
3131 * @param {string} [prefill] An optional prefill for the prompt.3137 * @prop {boolean} [trimNames] Whether to allow trimming "{{user}}:" and "{{char}}:" from the response.
3132 * @param {AdditionalRequestOptions} [options] Additional options for generation3138 * @prop {string} [prefill] An optional prefill for the prompt.
3139 * @prop {object} [jsonSchema] JSON schema to use for the structured generation. Usually requires a special instruction.
3140 * @param {GenerateRawParams} params Parameters for generating a message
3133 * @returns {Promise<string>} Generated message3141 * @returns {Promise<string>} Generated message
3134 */3142 */
3135export async function generateRaw(prompt, api, instructOverride, quietToLoud, systemPrompt, responseLength, trimNames = true, prefill = '', options = {}) {3143export async function generateRaw({ prompt = '', api = null, instructOverride = false, quietToLoud = false, systemPrompt = '', responseLength = null, trimNames = true, prefill = '', jsonSchema = null } = {}) {
3144 if (arguments.length > 0 && typeof arguments[0] !== 'object') {
3145 console.trace('generateRaw called with positional arguments. Please use an object instead.');
3146 [prompt, api, instructOverride, quietToLoud, systemPrompt, responseLength, trimNames, prefill, jsonSchema] = arguments;
3147 }
3148
3136 if (!api) {3149 if (!api) {
3137 api = main_api;3150 api = main_api;
3138 }3151 }
@@ -3184,7 +3197,7 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
3184 if (api === 'koboldhorde') {3197 if (api === 'koboldhorde') {
3185 data = await generateHorde(prompt.toString(), generateData, abortController.signal, false);3198 data = await generateHorde(prompt.toString(), generateData, abortController.signal, false);
3186 } else if (api === 'openai') {3199 } else if (api === 'openai') {
3187 data = await sendOpenAIRequest('quiet', generateData, abortController.signal, options);3200 data = await sendOpenAIRequest('quiet', generateData, abortController.signal, { jsonSchema });
3188 } else {3201 } else {
3189 const generateUrl = getGenerateUrl(api);3202 const generateUrl = getGenerateUrl(api);
3190 const response = await fetch(generateUrl, {3203 const response = await fetch(generateUrl, {
@@ -3209,7 +3222,7 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
3209 throw new Error(data.response);3222 throw new Error(data.response);
3210 }3223 }
32113224
3212 if (options?.jsonSchema) {3225 if (jsonSchema) {
3213 return extractJsonFromData(data, { mainApi: api });3226 return extractJsonFromData(data, { mainApi: api });
3214 }3227 }
32153228
@@ -9315,7 +9328,7 @@ function addDebugFunctions() {
9315 registerDebugFunction('generationTest', 'Send a generation request', 'Generates text using the currently selected API.', async () => {9328 registerDebugFunction('generationTest', 'Send a generation request', 'Generates text using the currently selected API.', async () => {
9316 const text = prompt('Input text:', 'Hello');9329 const text = prompt('Input text:', 'Hello');
9317 toastr.info('Working on it...');9330 toastr.info('Working on it...');
9318 const message = await generateRaw(text, null, false, false);9331 const message = await generateRaw({ prompt: text });
9319 alert(message);9332 alert(message);
9320 });9333 });
9321 registerDebugFunction('toggleEventTracing', 'Toggle event tracing', 'Useful to see what triggered a certain event.', () => {9334 registerDebugFunction('toggleEventTracing', 'Toggle event tracing', 'Useful to see what triggered a certain event.', () => {
public/scripts/backgrounds.js+1 -1
@@ -421,7 +421,7 @@ async function autoBackgroundCommand() {
421421
422 const list = options.map(option => `- ${option.text}`).join('\n');422 const list = options.map(option => `- ${option.text}`).join('\n');
423 const prompt = stringFormat(autoBgPrompt, list);423 const prompt = stringFormat(autoBgPrompt, list);
424 const reply = await generateQuietPrompt(prompt, false, false);424 const reply = await generateQuietPrompt({ quietPrompt: prompt });
425 const fuse = new Fuse(options, { keys: ['text'] });425 const fuse = new Fuse(options, { keys: ['text'] });
426 const bestMatch = fuse.search(reply, { limit: 1 });426 const bestMatch = fuse.search(reply, { limit: 1 });
427427
public/scripts/extensions/expressions/index.js+3 -3
@@ -1,6 +1,6 @@
1import { Fuse } from '../../../lib.js';1import { Fuse } from '../../../lib.js';
22
3import { characters, eventSource, event_types, generateQuietPrompt, generateRaw, getRequestHeaders, main_api, online_status, saveSettingsDebounced, substituteParams, substituteParamsExtended, system_message_types, this_chid } from '../../../script.js';3import { characters, eventSource, event_types, generateQuietPrompt, generateRaw, getRequestHeaders, online_status, saveSettingsDebounced, substituteParams, substituteParamsExtended, system_message_types, this_chid } from '../../../script.js';
4import { dragElement, isMobile } from '../../RossAscends-mods.js';4import { dragElement, isMobile } from '../../RossAscends-mods.js';
5import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplateAsync } from '../../extensions.js';5import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch, renderExtensionTemplateAsync } from '../../extensions.js';
6import { loadMovingUIState, performFuzzySearch, power_user } from '../../power-user.js';6import { loadMovingUIState, performFuzzySearch, power_user } from '../../power-user.js';
@@ -1056,10 +1056,10 @@ export async function getExpressionLabel(text, expressionsApi = extension_settin
1056 inApiCall = true;1056 inApiCall = true;
1057 switch (extension_settings.expressions.promptType) {1057 switch (extension_settings.expressions.promptType) {
1058 case PROMPT_TYPE.raw:1058 case PROMPT_TYPE.raw:
1059 emotionResponse = await generateRaw(text, main_api, false, false, prompt);1059 emotionResponse = await generateRaw({ prompt: text, systemPrompt: prompt });
1060 break;1060 break;
1061 case PROMPT_TYPE.full:1061 case PROMPT_TYPE.full:
1062 emotionResponse = await generateQuietPrompt(prompt, false, false);1062 emotionResponse = await generateQuietPrompt({ quietPrompt: prompt });
1063 break;1063 break;
1064 }1064 }
1065 } finally {1065 } finally {
public/scripts/extensions/memory/index.js+15 -3
@@ -506,7 +506,7 @@ async function summarizeCallback(args, text) {
506 case summary_sources.extras:506 case summary_sources.extras:
507 return await callExtrasSummarizeAPI(text);507 return await callExtrasSummarizeAPI(text);
508 case summary_sources.main:508 case summary_sources.main:
509 return removeReasoningFromString(await generateRaw(text, '', false, false, prompt, extension_settings.memory.overrideResponseLength));509 return removeReasoningFromString(await generateRaw({ prompt: text, systemPrompt: prompt, responseLength: extension_settings.memory.overrideResponseLength }));
510 case summary_sources.webllm: {510 case summary_sources.webllm: {
511 const messages = [{ role: 'system', content: prompt }, { role: 'user', content: text }].filter(m => m.content);511 const messages = [{ role: 'system', content: prompt }, { role: 'user', content: text }].filter(m => m.content);
512 const params = extension_settings.memory.overrideResponseLength > 0 ? { max_tokens: extension_settings.memory.overrideResponseLength } : {};512 const params = extension_settings.memory.overrideResponseLength > 0 ? { max_tokens: extension_settings.memory.overrideResponseLength } : {};
@@ -677,7 +677,13 @@ async function summarizeChatMain(context, force, skipWIAN) {
677 if (prompt_builders.DEFAULT === extension_settings.memory.prompt_builder) {677 if (prompt_builders.DEFAULT === extension_settings.memory.prompt_builder) {
678 try {678 try {
679 inApiCall = true;679 inApiCall = true;
680 summary = await generateQuietPrompt(prompt, false, skipWIAN, '', '', extension_settings.memory.overrideResponseLength);680 /** @type {import('../../../script.js').GenerateQuietPromptParams} */
681 const params = {
682 quietPrompt: prompt,
683 skipWIAN: skipWIAN,
684 responseLength: extension_settings.memory.overrideResponseLength,
685 };
686 summary = await generateQuietPrompt(params);
681 } finally {687 } finally {
682 inApiCall = false;688 inApiCall = false;
683 }689 }
@@ -701,7 +707,13 @@ async function summarizeChatMain(context, force, skipWIAN) {
701 return null;707 return null;
702 }708 }
703709
704 const rawSummary = await generateRaw(rawPrompt, '', false, false, prompt, extension_settings.memory.overrideResponseLength);710 /** @type {import('../../../script.js').GenerateRawParams} */
711 const params = {
712 prompt: rawPrompt,
713 systemPrompt: prompt,
714 responseLength: extension_settings.memory.overrideResponseLength,
715 };
716 const rawSummary = await generateRaw(params);
705 summary = removeReasoningFromString(rawSummary);717 summary = removeReasoningFromString(rawSummary);
706 index = lastUsedIndex;718 index = lastUsedIndex;
707 } finally {719 } finally {
public/scripts/extensions/stable-diffusion/index.js+1 -1
@@ -2726,7 +2726,7 @@ function getUserAvatarUrl() {
2726 * @returns {Promise<string>} - A promise that resolves when the prompt generation completes.2726 * @returns {Promise<string>} - A promise that resolves when the prompt generation completes.
2727 */2727 */
2728async function generatePrompt(quietPrompt) {2728async function generatePrompt(quietPrompt) {
2729 const reply = await generateQuietPrompt(quietPrompt, false, false);2729 const reply = await generateQuietPrompt({ quietPrompt });
2730 const processedReply = processReply(reply);2730 const processedReply = processReply(reply);
27312731
2732 if (!processedReply) {2732 if (!processedReply) {
public/scripts/extensions/vectors/index.js+3 -3
@@ -257,17 +257,17 @@ async function summarizeExtra(element) {
257/**257/**
258 * Summarizes messages using the main API method.258 * Summarizes messages using the main API method.
259 * @param {HashedMessage} element hashed message259 * @param {HashedMessage} element hashed message
260 * @returns {Promise<boolean>} Sucess260 * @returns {Promise<boolean>} Success
261 */261 */
262async function summarizeMain(element) {262async function summarizeMain(element) {
263 element.text = removeReasoningFromString(await generateRaw(element.text, '', false, false, settings.summary_prompt));263 element.text = removeReasoningFromString(await generateRaw({ prompt: element.text, systemPrompt: settings.summary_prompt }));
264 return true;264 return true;
265}265}
266266
267/**267/**
268 * Summarizes messages using WebLLM.268 * Summarizes messages using WebLLM.
269 * @param {HashedMessage} element hashed message269 * @param {HashedMessage} element hashed message
270 * @returns {Promise<boolean>} Sucess270 * @returns {Promise<boolean>} Success
271 */271 */
272async function summarizeWebLLM(element) {272async function summarizeWebLLM(element) {
273 if (!isWebLlmSupported()) {273 if (!isWebLlmSupported()) {
public/scripts/slash-commands.js+21 -4
@@ -3645,7 +3645,17 @@ async function generateRawCallback(args, value) {
3645 }3645 }
36463646
3647 setEphemeralStopStrings(resolveVariable(args?.stop));3647 setEphemeralStopStrings(resolveVariable(args?.stop));
3648 const result = await generateRaw(value, '', isFalseBoolean(args?.instruct), quietToLoud, systemPrompt, length, trimNames, prefillPrompt);3648 /** @type {import('../script.js').GenerateRawParams} */
3649 const params = {
3650 prompt: value,
3651 instructOverride: isFalseBoolean(args?.instruct),
3652 quietToLoud: quietToLoud,
3653 systemPrompt: systemPrompt,
3654 responseLength: length,
3655 trimNames: trimNames,
3656 prefill: prefillPrompt,
3657 };
3658 const result = await generateRaw(params);
3649 return result;3659 return result;
3650 } catch (err) {3660 } catch (err) {
3651 console.error('Error on /genraw generation', err);3661 console.error('Error on /genraw generation', err);
@@ -3681,7 +3691,14 @@ async function generateCallback(args, value) {
3681 setEphemeralStopStrings(resolveVariable(args?.stop));3691 setEphemeralStopStrings(resolveVariable(args?.stop));
3682 const name = args?.name;3692 const name = args?.name;
3683 const char = findChar({ name: name });3693 const char = findChar({ name: name });
3684 const result = await generateQuietPrompt(value, quietToLoud, false, '', char?.name ?? name, length);3694 /** @type {import('../script.js').GenerateQuietPromptParams} */
3695 const params = {
3696 quietPrompt: value,
3697 quietToLoud: quietToLoud,
3698 quietName: char?.name ?? name,
3699 responseLength: length,
3700 };
3701 const result = await generateQuietPrompt(params);
3685 return result;3702 return result;
3686 } catch (err) {3703 } catch (err) {
3687 console.error('Error on /gen generation', err);3704 console.error('Error on /gen generation', err);
@@ -4352,7 +4369,7 @@ export async function generateSystemMessage(_, prompt) {
43524369
4353 // Generate and regex the output if applicable4370 // Generate and regex the output if applicable
4354 toastr.info('Please wait', 'Generating...');4371 toastr.info('Please wait', 'Generating...');
4355 let message = await generateQuietPrompt(prompt, false, false);4372 let message = await generateQuietPrompt({ quietPrompt: prompt });
4356 message = getRegexedString(message, regex_placement.SLASH_COMMAND);4373 message = getRegexedString(message, regex_placement.SLASH_COMMAND);
43574374
4358 sendNarratorMessage(_, message);4375 sendNarratorMessage(_, message);
@@ -4609,7 +4626,7 @@ export async function promptQuietForLoudResponse(who, text) {
46094626
4610 //text = `${text}${power_user.instruct.enabled ? '' : '\n'}${(power_user.always_force_name2 && who != 'raw') ? characters[character_id].name + ":" : ""}`4627 //text = `${text}${power_user.instruct.enabled ? '' : '\n'}${(power_user.always_force_name2 && who != 'raw') ? characters[character_id].name + ":" : ""}`
46114628
4612 let reply = await generateQuietPrompt(text, true, false);4629 let reply = await generateQuietPrompt({ quietPrompt: text, quietToLoud: true });
4613 text = await getRegexedString(reply, regex_placement.SLASH_COMMAND);4630 text = await getRegexedString(reply, regex_placement.SLASH_COMMAND);
46144631
4615 const message = {4632 const message = {