Merge branch 'parse-reasoning-command-args' into reasoning-parsing-streaming
| @@ -10,7 +10,8 @@ import { Popup } from './popup.js'; | ||
| 10 | 10 | import { power_user } from './power-user.js'; |
| 11 | 11 | import { SlashCommand } from './slash-commands/SlashCommand.js'; |
| 12 | 12 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from './slash-commands/SlashCommandArgument.js'; |
| 13 | 13 | import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 14 | +import { enumTypes, SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js'; | |
| 14 | 15 | import { SlashCommandParser } from './slash-commands/SlashCommandParser.js'; |
| 15 | 16 | import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js'; |
| 16 | 17 | import { copyText, escapeRegex, isFalseBoolean, setDatasetProperty, trimSpaces } from './utils.js'; |
| @@ -678,7 +679,26 @@ function registerReasoningSlashCommands() { | ||
| 678 | 679 | typeList: [ARGUMENT_TYPE.BOOLEAN], |
| 679 | 680 | defaultValue: 'true', |
| 680 | 681 | isRequired: false, |
| 681 | 682 | enumProviderenumList: commonEnumProviders.boolean('trueFalse')(), |
| 683 | + }), | |
| 684 | + SlashCommandNamedArgument.fromProps({ | |
| 685 | + name: 'return', | |
| 686 | + description: 'Whether to return the parsed reasoning or the content without reasoning', | |
| 687 | + typeList: [ARGUMENT_TYPE.STRING], | |
| 688 | + defaultValue: 'reasoning', | |
| 689 | + isRequired: false, | |
| 690 | + enumList: [ | |
| 691 | + new SlashCommandEnumValue('reasoning', null, enumTypes.enum, enumIcons.reasoning), | |
| 692 | + new SlashCommandEnumValue('content', null, enumTypes.enum, enumIcons.message), | |
| 693 | + ], | |
| 694 | + }), | |
| 695 | + SlashCommandNamedArgument.fromProps({ | |
| 696 | + name: 'strict', | |
| 697 | + description: 'Whether to require the reasoning block to be at the beginning of the string (excluding whitespaces).', | |
| 698 | + typeList: [ARGUMENT_TYPE.BOOLEAN], | |
| 699 | + defaultValue: 'true', | |
| 700 | + isRequired: false, | |
| 701 | + enumList: commonEnumProviders.boolean('trueFalse')(), | |
| 682 | 702 | }), |
| 683 | 703 | ], |
| 684 | 704 | unnamedArgumentList: [ |
| @@ -688,19 +708,27 @@ function registerReasoningSlashCommands() { | ||
| 688 | 708 | }), |
| 689 | 709 | ], |
| 690 | 710 | callback: (args, value) => { |
| 691 | 711 | if (!value || typeof value !== 'string') { |
| 692 | 712 | return ''; |
| 693 | 713 | } |
| 694 | 714 | |
| 695 | 715 | if (!power_user.reasoning.prefix || !power_user.reasoning.suffix) { |
| 696 | 716 | toastr.warning(t`Both prefix and suffix must be set in the Reasoning Formatting settings.`, t`Reasoning Parse`); |
| 697 | 717 | return String(value); |
| 718 | + } | |
| 719 | + if (typeof args.return !== 'string' || !['reasoning', 'content'].includes(args.return)) { | |
| 720 | + toastr.warning(t`Invalid return type '${args.return}', defaulting to 'reasoning'.`, t`Reasoning Parse`); | |
| 698 | 721 | } |
| 699 | 722 | |
| 700 | - const parsedReasoning = parseReasoningFromString(String(value)); | |
| 723 | + const returnMessage = args.return === 'content'; | |
| 701 | 724 | |
| 725 | + const parsedReasoning = parseReasoningFromString(value, { strict: !isFalseBoolean(String(args.strict ?? '')) }); | |
| 702 | 726 | if (!parsedReasoning) { |
| 703 | 727 | return returnMessage ? value : ''; |
| 728 | + } | |
| 729 | + | |
| 730 | + if (returnMessage) { | |
| 731 | + return parsedReasoning.content; | |
| 704 | 732 | } |
| 705 | 733 | |
| 706 | 734 | const applyRegex = !isFalseBoolean(String(args.regex ?? '')); |
| @@ -902,16 +930,18 @@ export function removeReasoningFromString(str) { | ||
| 902 | 930 | * @property {string} reasoning Reasoning block |
| 903 | 931 | * @property {string} content Message content |
| 904 | 932 | * @param {string} str Content of the message |
| 933 | + * @param {Object} options Optional arguments | |
| 934 | + * @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 | |
| 905 | 935 | * @returns {ParsedReasoning|null} Parsed reasoning block and message content |
| 906 | 936 | */ |
| 907 | 937 | function parseReasoningFromString(str, { strict = true } = {}) { |
| 908 | 938 | // Both prefix and suffix must be defined |
| 909 | 939 | if (!power_user.reasoning.prefix || !power_user.reasoning.suffix) { |
| 910 | 940 | return null; |
| 911 | 941 | } |
| 912 | 942 | |
| 913 | 943 | try { |
| 914 | 944 | const regex = new RegExp(`${(strict ? '^\\s*?' : '')}${escapeRegex(power_user.reasoning.prefix)}(.*?)${escapeRegex(power_user.reasoning.suffix)}`, 's'); |
| 915 | 945 | |
| 916 | 946 | let didReplace = false; |
| 917 | 947 | let reasoning = ''; |
| @@ -34,6 +34,7 @@ export const enumIcons = { | ||
| 34 | 34 | preset: '⚙️', |
| 35 | 35 | file: '📄', |
| 36 | 36 | message: '💬', |
| 37 | + reasoning: '💡', | |
| 37 | 38 | voice: '🎤', |
| 38 | 39 | server: '🖥️', |
| 39 | 40 | popup: '🗔', |