Add 'return' and 'strict' to /reasoning-parse - Add 'return' arg to `/reasoning-parse` to decide whether to return the reasoning, or the content without reasoning. Defaulting to reasoning. - Add 'strict' arg to `/reasoning-parse` to decide whether the reasoning block has to be at the beginning of the provided message or not. Defaulting to true. - Update parsing of all reasoning (even the auto parse one) to be strict by default - meaning the regex block has to be at the beginning (excluding whitespaces)

1ad3a2b968abe181aa6e362b358c4fac74cab3ce

Wolfsblvt <wolfsblvt@gmail.com>

2 files changed, +40 -9Ignore whitespace
public/scripts/reasoning.js+39 -9
@@ -10,7 +10,8 @@ import { Popup } from './popup.js';
1010import { power_user } from './power-user.js';
1111import { SlashCommand } from './slash-commands/SlashCommand.js';
1212import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js';
1313import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js';
14+import { enumTypes, SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
1415import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
1516import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
1617import { copyText, escapeRegex, isFalseBoolean, setDatasetProperty } from './utils.js';
@@ -598,7 +599,26 @@ function registerReasoningSlashCommands() {
598599 typeList: [ARGUMENT_TYPE.BOOLEAN],
599600 defaultValue: 'true',
600601 isRequired: false,
601602 enumProviderenumList: commonEnumProviders.boolean('trueFalse')(),
603+ }),
604+ SlashCommandNamedArgument.fromProps({
605+ name: 'return',
606+ description: 'Whether to return the parsed reasoning or the content without reasoning',
607+ typeList: [ARGUMENT_TYPE.STRING],
608+ defaultValue: 'reasoning',
609+ isRequired: false,
610+ enumList: [
611+ new SlashCommandEnumValue('reasoning', null, enumTypes.enum, enumIcons.reasoning),
612+ new SlashCommandEnumValue('content', null, enumTypes.enum, enumIcons.message),
613+ ],
614+ }),
615+ SlashCommandNamedArgument.fromProps({
616+ name: 'strict',
617+ description: 'Whether to require the reasoning block to be at the beginning of the string (excluding whitespaces).',
618+ typeList: [ARGUMENT_TYPE.BOOLEAN],
619+ defaultValue: 'true',
620+ isRequired: false,
621+ enumList: commonEnumProviders.boolean('trueFalse')(),
602622 }),
603623 ],
604624 unnamedArgumentList: [
@@ -608,19 +628,27 @@ function registerReasoningSlashCommands() {
608628 }),
609629 ],
610630 callback: (args, value) => {
611631 if (!value || typeof value !== 'string') {
612632 return '';
613633 }
614634
615635 if (!power_user.reasoning.prefix || !power_user.reasoning.suffix) {
616636 toastr.warning(t`Both prefix and suffix must be set in the Reasoning Formatting settings.`, t`Reasoning Parse`);
617637 return String(value);
638+ }
639+ if (typeof args.return !== 'string' || !['reasoning', 'content'].includes(args.return)) {
640+ toastr.warning(t`Invalid return type '${args.return}', defaulting to 'reasoning'.`, t`Reasoning Parse`);
618641 }
619642
620- const parsedReasoning = parseReasoningFromString(String(value));
643+ const returnMessage = args.return === 'content';
621644
645+ const parsedReasoning = parseReasoningFromString(value, { strict: !isFalseBoolean(String(args.strict ?? '')) });
622646 if (!parsedReasoning) {
623647 return returnMessage ? value : '';
648+ }
649+
650+ if (returnMessage) {
651+ return parsedReasoning.content;
624652 }
625653
626654 const applyRegex = !isFalseBoolean(String(args.regex ?? ''));
@@ -819,16 +847,18 @@ export function removeReasoningFromString(str) {
819847 * @property {string} reasoning Reasoning block
820848 * @property {string} content Message content
821849 * @param {string} str Content of the message
850+ * @param {Object} options Optional arguments
851+ * @param {boolean} [options.strict=true] Whether the reasoning block **has** to be at the beginning of the provided string (excluding whitespaces), or can be anywhere in it
822852 * @returns {ParsedReasoning|null} Parsed reasoning block and message content
823853 */
824854function parseReasoningFromString(str, { strict = true } = {}) {
825855 // Both prefix and suffix must be defined
826856 if (!power_user.reasoning.prefix || !power_user.reasoning.suffix) {
827857 return null;
828858 }
829859
830860 try {
831861 const regex = new RegExp(`${(strict ? '^\\s*?' : '')}${escapeRegex(power_user.reasoning.prefix)}(.*?)${escapeRegex(power_user.reasoning.suffix)}`, 's');
832862
833863 let didReplace = false;
834864 let reasoning = '';
public/scripts/slash-commands/SlashCommandCommonEnumsProvider.js+1 -0
@@ -34,6 +34,7 @@ export const enumIcons = {
3434 preset: '⚙️',
3535 file: '📄',
3636 message: '💬',
37+ reasoning: '💡',
3738 voice: '🎤',
3839 server: '🖥️',
3940 popup: '🗔',