Add trim argument to /gen and /sysgen. Closes #4361
| @@ -2345,10 +2345,12 @@ export function getStoppingStrings(isImpersonate, isContinue) { | |||
| 2345 | * @prop {number} [responseLength] Maximum response length. If unset, the global default value is used. | 2345 | * @prop {number} [responseLength] Maximum response length. If unset, the global default value is used. |
| 2346 | * @prop {number} [forceChId] Character ID to use for this generation run. Works in groups only. | 2346 | * @prop {number} [forceChId] Character ID to use for this generation run. Works in groups only. |
| 2347 | * @prop {object} [jsonSchema] JSON schema to use for the structured generation. Usually requires a special instruction. | 2347 | * @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 | ||
| 2348 | * @param {GenerateQuietPromptParams} params Parameters for the quiet prompt generation | 2350 | * @param {GenerateQuietPromptParams} params Parameters for the quiet prompt generation |
| 2349 | * @returns {Promise<string>} Generated text. If using structured output, will contain a serialized JSON object. | 2351 | * @returns {Promise<string>} Generated text. If using structured output, will contain a serialized JSON object. |
| 2350 | */ | 2352 | */ |
| 2351 | export async function generateQuietPrompt({ quietPrompt = '', quietToLoud = false, skipWIAN = false, quietImage = null, quietName = null, responseLength = null, forceChId = null, jsonSchema = null } = {}) { | 2353 | export async function generateQuietPrompt({ quietPrompt = '', quietToLoud = false, skipWIAN = false, quietImage = null, quietName = null, responseLength = null, forceChId = null, jsonSchema = null, removeReasoning = true, trimToSentence = false } = {}) { |
| 2352 | if (arguments.length > 0 && typeof arguments[0] !== 'object') { | 2354 | if (arguments.length > 0 && typeof arguments[0] !== 'object') { |
| 2353 | console.trace('generateQuietPrompt called with positional arguments. Please use an object instead.'); | 2355 | console.trace('generateQuietPrompt called with positional arguments. Please use an object instead.'); |
| 2354 | [quietPrompt, quietToLoud, skipWIAN, quietImage, quietName, responseLength, forceChId, jsonSchema] = arguments; | 2356 | [quietPrompt, quietToLoud, skipWIAN, quietImage, quietName, responseLength, forceChId, jsonSchema] = arguments; |
| @@ -2372,8 +2374,10 @@ export async function generateQuietPrompt({ quietPrompt = '', quietToLoud = fals | |||
| 2372 | TempResponseLength.save(main_api, responseLength); | 2374 | TempResponseLength.save(main_api, responseLength); |
| 2373 | eventHook = TempResponseLength.setupEventHook(main_api); | 2375 | eventHook = TempResponseLength.setupEventHook(main_api); |
| 2374 | } | 2376 | } |
| 2375 | const result = await Generate('quiet', generateOptions); | 2377 | let result = await Generate('quiet', generateOptions); |
| 2376 | return removeReasoningFromString(result); | 2378 | result = trimToSentence ? trimToEndSentence(result) : result; |
| 2379 | result = removeReasoning ? removeReasoningFromString(result) : result; | ||
| 2380 | return result; | ||
| 2377 | } finally { | 2381 | } finally { |
| 2378 | if (responseLengthCustomized && TempResponseLength.isCustomized()) { | 2382 | if (responseLengthCustomized && TempResponseLength.isCustomized()) { |
| 2379 | TempResponseLength.restore(main_api); | 2383 | TempResponseLength.restore(main_api); |
| @@ -1083,6 +1083,44 @@ export function initDefaultSlashCommands() { | |||
| 1083 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ | 1083 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ |
| 1084 | name: 'sysgen', | 1084 | name: 'sysgen', |
| 1085 | callback: generateSystemMessage, | 1085 | 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 | ], | ||
| 1086 | unnamedArgumentList: [ | 1124 | unnamedArgumentList: [ |
| 1087 | new SlashCommandArgument( | 1125 | new SlashCommandArgument( |
| 1088 | 'prompt', [ARGUMENT_TYPE.STRING], true, | 1126 | 'prompt', [ARGUMENT_TYPE.STRING], true, |
| @@ -1629,6 +1667,14 @@ export function initDefaultSlashCommands() { | |||
| 1629 | callback: generateCallback, | 1667 | callback: generateCallback, |
| 1630 | returns: 'generated text', | 1668 | returns: 'generated text', |
| 1631 | namedArgumentList: [ | 1669 | 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 | }), | ||
| 1632 | new SlashCommandNamedArgument( | 1678 | new SlashCommandNamedArgument( |
| 1633 | 'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), | 1679 | 'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(), |
| 1634 | ), | 1680 | ), |
| @@ -3679,6 +3725,7 @@ async function generateCallback(args, value) { | |||
| 3679 | // Prevent generate recursion | 3725 | // Prevent generate recursion |
| 3680 | $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true })); | 3726 | $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true })); |
| 3681 | const lock = isTrueBoolean(args?.lock); | 3727 | const lock = isTrueBoolean(args?.lock); |
| 3728 | const trim = isTrueBoolean(args?.trim?.toString()); | ||
| 3682 | const as = args?.as || 'system'; | 3729 | const as = args?.as || 'system'; |
| 3683 | const quietToLoud = as === 'char'; | 3730 | const quietToLoud = as === 'char'; |
| 3684 | const length = Number(resolveVariable(args?.length) ?? 0) || 0; | 3731 | const length = Number(resolveVariable(args?.length) ?? 0) || 0; |
| @@ -3697,6 +3744,7 @@ async function generateCallback(args, value) { | |||
| 3697 | quietToLoud: quietToLoud, | 3744 | quietToLoud: quietToLoud, |
| 3698 | quietName: char?.name ?? name, | 3745 | quietName: char?.name ?? name, |
| 3699 | responseLength: length, | 3746 | responseLength: length, |
| 3747 | trimToSentence: trim, | ||
| 3700 | }; | 3748 | }; |
| 3701 | const result = await generateQuietPrompt(params); | 3749 | const result = await generateQuietPrompt(params); |
| 3702 | return result; | 3750 | return result; |
| @@ -4358,7 +4406,7 @@ async function continueChatCallback(args, prompt) { | |||
| 4358 | return ''; | 4406 | return ''; |
| 4359 | } | 4407 | } |
| 4360 | 4408 | ||
| 4361 | export async function generateSystemMessage(_, prompt) { | 4409 | export async function generateSystemMessage(args, prompt) { |
| 4362 | $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true })); | 4410 | $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true })); |
| 4363 | 4411 | ||
| 4364 | if (!prompt) { | 4412 | if (!prompt) { |
| @@ -4367,13 +4415,14 @@ export async function generateSystemMessage(_, prompt) { | |||
| 4367 | return ''; | 4415 | return ''; |
| 4368 | } | 4416 | } |
| 4369 | 4417 | ||
| 4418 | const trim = isTrueBoolean(args?.trim?.toString()); | ||
| 4419 | |||
| 4370 | // Generate and regex the output if applicable | 4420 | // Generate and regex the output if applicable |
| 4371 | toastr.info('Please wait', 'Generating...'); | 4421 | const toast = toastr.info('Please wait', 'Generating...'); |
| 4372 | let message = await generateQuietPrompt({ quietPrompt: prompt }); | 4422 | const message = await generateQuietPrompt({ quietPrompt: prompt, trimToSentence: trim }); |
| 4373 | message = getRegexedString(message, regex_placement.SLASH_COMMAND); | 4423 | toastr.clear(toast); |
| 4374 | 4424 | ||
| 4375 | sendNarratorMessage(_, message); | 4425 | return await sendNarratorMessage(args, getRegexedString(message, regex_placement.SLASH_COMMAND)); |
| 4376 | return ''; | ||
| 4377 | } | 4426 | } |
| 4378 | 4427 | ||
| 4379 | function setStoryModeCallback() { | 4428 | function setStoryModeCallback() { |