Add trim argument to /gen and /sysgen. Closes #4361

fb058816e86b71e769c2dbe3e50db24d5028676a

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

2 files changed, +62 -9Showing whitespace changes
public/script.js+7 -3
@@ -2345,10 +2345,12 @@ export function getStoppingStrings(isImpersonate, isContinue) {
23452345 * @prop {number} [responseLength] Maximum response length. If unset, the global default value is used.
23462346 * @prop {number} [forceChId] Character ID to use for this generation run. Works in groups only.
23472347 * @prop {object} [jsonSchema] JSON schema to use for the structured generation. Usually requires a special instruction.
2348+ * @prop {boolean} [removeReasoning] Parses and removes the reasoning block according to reasoning format preferences
2349+ * @prop {boolean} [trimToSentence] Whether to trim the response to the last complete sentence
23482350 * @param {GenerateQuietPromptParams} params Parameters for the quiet prompt generation
23492351 * @returns {Promise<string>} Generated text. If using structured output, will contain a serialized JSON object.
23502352 */
23512353export async function generateQuietPrompt({ quietPrompt = '', quietToLoud = false, skipWIAN = false, quietImage = null, quietName = null, responseLength = null, forceChId = null, jsonSchema = null, removeReasoning = true, trimToSentence = false } = {}) {
23522354 if (arguments.length > 0 && typeof arguments[0] !== 'object') {
23532355 console.trace('generateQuietPrompt called with positional arguments. Please use an object instead.');
23542356 [quietPrompt, quietToLoud, skipWIAN, quietImage, quietName, responseLength, forceChId, jsonSchema] = arguments;
@@ -2372,8 +2374,10 @@ export async function generateQuietPrompt({ quietPrompt = '', quietToLoud = fals
23722374 TempResponseLength.save(main_api, responseLength);
23732375 eventHook = TempResponseLength.setupEventHook(main_api);
23742376 }
23752377 constlet result = await Generate('quiet', generateOptions);
2376- return removeReasoningFromString(result);
2378+ result = trimToSentence ? trimToEndSentence(result) : result;
2379+ result = removeReasoning ? removeReasoningFromString(result) : result;
2380+ return result;
23772381 } finally {
23782382 if (responseLengthCustomized && TempResponseLength.isCustomized()) {
23792383 TempResponseLength.restore(main_api);
public/scripts/slash-commands.js+55 -6
@@ -1083,6 +1083,44 @@ export function initDefaultSlashCommands() {
10831083 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
10841084 name: 'sysgen',
10851085 callback: generateSystemMessage,
1086+ namedArgumentList: [
1087+ SlashCommandNamedArgument.fromProps({
1088+ name: 'trim',
1089+ description: 'Trim the output by the last sentence boundary',
1090+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1091+ defaultValue: 'false',
1092+ isRequired: false,
1093+ enumProvider: commonEnumProviders.boolean('trueFalse'),
1094+ }),
1095+ SlashCommandNamedArgument.fromProps({
1096+ name: 'compact',
1097+ description: 'Use a compact layout for the message',
1098+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1099+ defaultValue: 'false',
1100+ isRequired: false,
1101+ acceptsMultiple: false,
1102+ enumProvider: commonEnumProviders.boolean('trueFalse'),
1103+ }),
1104+ SlashCommandNamedArgument.fromProps({
1105+ name: 'at',
1106+ description: 'Position to insert the message (index-based, corresponding to message id). If not set, the message will be inserted at the end of the chat.\nNegative values (including -0) are accepted and will work similarly to how \'depth\' usually works. For example, -1 will insert the message right before the last message in chat.',
1107+ typeList: [ARGUMENT_TYPE.NUMBER],
1108+ enumProvider: commonEnumProviders.messages({ allowIdAfter: true }),
1109+ }),
1110+ SlashCommandNamedArgument.fromProps({
1111+ name: 'name',
1112+ description: 'Optional custom display name to use for this system narrator message.',
1113+ typeList: [ARGUMENT_TYPE.STRING],
1114+ }),
1115+ SlashCommandNamedArgument.fromProps({
1116+ name: 'return',
1117+ description: 'The way how you want the return value to be provided',
1118+ typeList: [ARGUMENT_TYPE.STRING],
1119+ defaultValue: 'none',
1120+ enumList: slashCommandReturnHelper.enumList({ allowObject: true }),
1121+ forceEnum: true,
1122+ }),
1123+ ],
10861124 unnamedArgumentList: [
10871125 new SlashCommandArgument(
10881126 'prompt', [ARGUMENT_TYPE.STRING], true,
@@ -1629,6 +1667,14 @@ export function initDefaultSlashCommands() {
16291667 callback: generateCallback,
16301668 returns: 'generated text',
16311669 namedArgumentList: [
1670+ SlashCommandNamedArgument.fromProps({
1671+ name: 'trim',
1672+ description: 'Trim the output by the last sentence boundary',
1673+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1674+ defaultValue: 'false',
1675+ isRequired: false,
1676+ enumProvider: commonEnumProviders.boolean('trueFalse'),
1677+ }),
16321678 new SlashCommandNamedArgument(
16331679 'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(),
16341680 ),
@@ -3679,6 +3725,7 @@ async function generateCallback(args, value) {
36793725 // Prevent generate recursion
36803726 $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true }));
36813727 const lock = isTrueBoolean(args?.lock);
3728+ const trim = isTrueBoolean(args?.trim?.toString());
36823729 const as = args?.as || 'system';
36833730 const quietToLoud = as === 'char';
36843731 const length = Number(resolveVariable(args?.length) ?? 0) || 0;
@@ -3697,6 +3744,7 @@ async function generateCallback(args, value) {
36973744 quietToLoud: quietToLoud,
36983745 quietName: char?.name ?? name,
36993746 responseLength: length,
3747+ trimToSentence: trim,
37003748 };
37013749 const result = await generateQuietPrompt(params);
37023750 return result;
@@ -4358,7 +4406,7 @@ async function continueChatCallback(args, prompt) {
43584406 return '';
43594407}
43604408
43614409export async function generateSystemMessage(_args, prompt) {
43624410 $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true }));
43634411
43644412 if (!prompt) {
@@ -4367,13 +4415,14 @@ export async function generateSystemMessage(_, prompt) {
43674415 return '';
43684416 }
43694417
4418+ const trim = isTrueBoolean(args?.trim?.toString());
4419+
43704420 // Generate and regex the output if applicable
43714421 const toast = toastr.info('Please wait', 'Generating...');
43724422 letconst message = await generateQuietPrompt({ quietPrompt: prompt, trimToSentence: trim });
4373- message = getRegexedString(message, regex_placement.SLASH_COMMAND);
4423+ toastr.clear(toast);
43744424
43754425 return await sendNarratorMessage(_args, getRegexedString(message, regex_placement.SLASH_COMMAND));
4376- return '';
43774426}
43784427
43794428function setStoryModeCallback() {