Merge pull request #2564 from SillyTavern/instruct-mistral-large Add first/last user messages prefixes for instruct mode
Signed| @@ -3297,6 +3297,24 @@ | |||
| 3297 | </div> | 3297 | </div> |
| 3298 | </div> | 3298 | </div> |
| 3299 | <div class="flex-container"> | 3299 | <div class="flex-container"> |
| 3300 | <div class="flex1" title="Inserted before the first User's message." data-i18n="[title]Inserted before the first User's message."> | ||
| 3301 | <label for="instruct_first_input_sequence"> | ||
| 3302 | <small data-i18n="First User Prefix">First User Prefix</small> | ||
| 3303 | </label> | ||
| 3304 | <div> | ||
| 3305 | <textarea id="instruct_first_input_sequence" class="text_pole textarea_compact autoSetHeight" maxlength="2000" placeholder="—" rows="1"></textarea> | ||
| 3306 | </div> | ||
| 3307 | </div> | ||
| 3308 | <div class="flex1" title="Inserted before the last User's message." data-i18n="[title]instruct_last_input_sequence"> | ||
| 3309 | <label for="instruct_last_input_sequence"> | ||
| 3310 | <small data-i18n="Last User Prefix">Last User Prefix</small> | ||
| 3311 | </label> | ||
| 3312 | <div> | ||
| 3313 | <textarea id="instruct_last_input_sequence" class="text_pole wide100p textarea_compact autoSetHeight" maxlength="2000" placeholder="—" rows="1"></textarea> | ||
| 3314 | </div> | ||
| 3315 | </div> | ||
| 3316 | </div> | ||
| 3317 | <div class="flex-container"> | ||
| 3300 | <div class="flex1" title="Will be inserted as a last prompt line when using system/neutral generation." data-i18n="[title]Will be inserted as a last prompt line when using system/neutral generation."> | 3318 | <div class="flex1" title="Will be inserted as a last prompt line when using system/neutral generation." data-i18n="[title]Will be inserted as a last prompt line when using system/neutral generation."> |
| 3301 | <label for="instruct_last_system_sequence"> | 3319 | <label for="instruct_last_system_sequence"> |
| 3302 | <small data-i18n="System Instruction Prefix">System Instruction Prefix</small> | 3320 | <small data-i18n="System Instruction Prefix">System Instruction Prefix</small> |
| @@ -3611,6 +3611,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3611 | let chat2 = []; | 3611 | let chat2 = []; |
| 3612 | let continue_mag = ''; | 3612 | let continue_mag = ''; |
| 3613 | const userMessageIndices = []; | 3613 | const userMessageIndices = []; |
| 3614 | const lastUserMessageIndex = coreChat.findLastIndex(x => x.is_user); | ||
| 3614 | 3615 | ||
| 3615 | for (let i = coreChat.length - 1, j = 0; i >= 0; i--, j++) { | 3616 | for (let i = coreChat.length - 1, j = 0; i >= 0; i--, j++) { |
| 3616 | if (main_api == 'openai') { | 3617 | if (main_api == 'openai') { |
| @@ -3629,6 +3630,11 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3629 | chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.FIRST); | 3630 | chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.FIRST); |
| 3630 | } | 3631 | } |
| 3631 | 3632 | ||
| 3633 | if (lastUserMessageIndex >= 0 && j === lastUserMessageIndex && isInstruct) { | ||
| 3634 | // Reformat with the last input sequence (if any) | ||
| 3635 | chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.LAST); | ||
| 3636 | } | ||
| 3637 | |||
| 3632 | // Do not suffix the message for continuation | 3638 | // Do not suffix the message for continuation |
| 3633 | if (i === 0 && isContinue) { | 3639 | if (i === 0 && isContinue) { |
| 3634 | if (isInstruct) { | 3640 | if (isInstruct) { |
| @@ -3654,7 +3660,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3654 | mes: power_user.instruct.user_alignment_message, | 3660 | mes: power_user.instruct.user_alignment_message, |
| 3655 | is_user: true, | 3661 | is_user: true, |
| 3656 | }; | 3662 | }; |
| 3657 | userAlignmentMessage = formatMessageHistoryItem(alignmentMessage, isInstruct, false); | 3663 | userAlignmentMessage = formatMessageHistoryItem(alignmentMessage, isInstruct, force_output_sequence.FIRST); |
| 3658 | } | 3664 | } |
| 3659 | 3665 | ||
| 3660 | // Call combined AN into Generate | 3666 | // Call combined AN into Generate |
| @@ -34,6 +34,8 @@ const controls = [ | |||
| 34 | { id: 'instruct_names_force_groups', property: 'names_force_groups', isCheckbox: true }, | 34 | { id: 'instruct_names_force_groups', property: 'names_force_groups', isCheckbox: true }, |
| 35 | { id: 'instruct_first_output_sequence', property: 'first_output_sequence', isCheckbox: false }, | 35 | { id: 'instruct_first_output_sequence', property: 'first_output_sequence', isCheckbox: false }, |
| 36 | { id: 'instruct_last_output_sequence', property: 'last_output_sequence', isCheckbox: false }, | 36 | { id: 'instruct_last_output_sequence', property: 'last_output_sequence', isCheckbox: false }, |
| 37 | { id: 'instruct_first_input_sequence', property: 'first_input_sequence', isCheckbox: false }, | ||
| 38 | { id: 'instruct_last_input_sequence', property: 'last_input_sequence', isCheckbox: false }, | ||
| 37 | { id: 'instruct_activation_regex', property: 'activation_regex', isCheckbox: false }, | 39 | { id: 'instruct_activation_regex', property: 'activation_regex', isCheckbox: false }, |
| 38 | { id: 'instruct_bind_to_context', property: 'bind_to_context', isCheckbox: true }, | 40 | { id: 'instruct_bind_to_context', property: 'bind_to_context', isCheckbox: true }, |
| 39 | { id: 'instruct_skip_examples', property: 'skip_examples', isCheckbox: true }, | 41 | { id: 'instruct_skip_examples', property: 'skip_examples', isCheckbox: true }, |
| @@ -58,6 +60,8 @@ function migrateInstructModeSettings(settings) { | |||
| 58 | system_suffix: '', | 60 | system_suffix: '', |
| 59 | user_alignment_message: '', | 61 | user_alignment_message: '', |
| 60 | last_system_sequence: '', | 62 | last_system_sequence: '', |
| 63 | first_input_sequence: '', | ||
| 64 | last_input_sequence: '', | ||
| 61 | names_force_groups: true, | 65 | names_force_groups: true, |
| 62 | skip_examples: false, | 66 | skip_examples: false, |
| 63 | system_same_as_user: false, | 67 | system_same_as_user: false, |
| @@ -253,7 +257,15 @@ export function getInstructStoppingSequences() { | |||
| 253 | const system_sequence = power_user.instruct.system_sequence?.replace(/{{name}}/gi, 'System') || ''; | 257 | const system_sequence = power_user.instruct.system_sequence?.replace(/{{name}}/gi, 'System') || ''; |
| 254 | const last_system_sequence = power_user.instruct.last_system_sequence?.replace(/{{name}}/gi, 'System') || ''; | 258 | const last_system_sequence = power_user.instruct.last_system_sequence?.replace(/{{name}}/gi, 'System') || ''; |
| 255 | 259 | ||
| 256 | const combined_sequence = `${stop_sequence}\n${input_sequence}\n${output_sequence}\n${first_output_sequence}\n${last_output_sequence}\n${system_sequence}\n${last_system_sequence}`; | 260 | const combined_sequence = [ |
| 261 | stop_sequence, | ||
| 262 | input_sequence, | ||
| 263 | output_sequence, | ||
| 264 | first_output_sequence, | ||
| 265 | last_output_sequence, | ||
| 266 | system_sequence, | ||
| 267 | last_system_sequence, | ||
| 268 | ].join('\n'); | ||
| 257 | 269 | ||
| 258 | combined_sequence.split('\n').filter((line, index, self) => self.indexOf(line) === index).forEach(addInstructSequence); | 270 | combined_sequence.split('\n').filter((line, index, self) => self.indexOf(line) === index).forEach(addInstructSequence); |
| 259 | } | 271 | } |
| @@ -301,6 +313,14 @@ export function formatInstructModeChat(name, mes, isUser, isNarrator, forceAvata | |||
| 301 | } | 313 | } |
| 302 | 314 | ||
| 303 | if (isUser) { | 315 | if (isUser) { |
| 316 | if (forceOutputSequence === force_output_sequence.FIRST) { | ||
| 317 | return power_user.instruct.first_input_sequence || power_user.instruct.input_sequence; | ||
| 318 | } | ||
| 319 | |||
| 320 | if (forceOutputSequence === force_output_sequence.LAST) { | ||
| 321 | return power_user.instruct.last_input_sequence || power_user.instruct.input_sequence; | ||
| 322 | } | ||
| 323 | |||
| 304 | return power_user.instruct.input_sequence; | 324 | return power_user.instruct.input_sequence; |
| 305 | } | 325 | } |
| 306 | 326 | ||
| @@ -552,6 +572,8 @@ export function replaceInstructMacros(input, env) { | |||
| 552 | 'instructStop': power_user.instruct.stop_sequence, | 572 | 'instructStop': power_user.instruct.stop_sequence, |
| 553 | 'instructUserFiller': power_user.instruct.user_alignment_message, | 573 | 'instructUserFiller': power_user.instruct.user_alignment_message, |
| 554 | 'instructSystemInstructionPrefix': power_user.instruct.last_system_sequence, | 574 | 'instructSystemInstructionPrefix': power_user.instruct.last_system_sequence, |
| 575 | 'instructFirstInput|instructFirstUserPrefix': power_user.instruct.first_input_sequence || power_user.instruct.input_sequence, | ||
| 576 | 'instructLastInput|instructLastUserPrefix': power_user.instruct.last_input_sequence || power_user.instruct.input_sequence, | ||
| 555 | }; | 577 | }; |
| 556 | 578 | ||
| 557 | for (const [placeholder, value] of Object.entries(instructMacros)) { | 579 | for (const [placeholder, value] of Object.entries(instructMacros)) { |
| @@ -2175,7 +2175,7 @@ function validateStoryString(storyString, params) { | |||
| 2175 | validateMissingField('personality'); | 2175 | validateMissingField('personality'); |
| 2176 | validateMissingField('persona'); | 2176 | validateMissingField('persona'); |
| 2177 | validateMissingField('scenario'); | 2177 | validateMissingField('scenario'); |
| 2178 | validateMissingField('system'); | 2178 | // validateMissingField('system'); |
| 2179 | validateMissingField('wiBefore', 'loreBefore'); | 2179 | validateMissingField('wiBefore', 'loreBefore'); |
| 2180 | validateMissingField('wiAfter', 'loreAfter'); | 2180 | validateMissingField('wiAfter', 'loreAfter'); |
| 2181 | 2181 | ||
| @@ -72,6 +72,8 @@ | |||
| 72 | <li><tt>{{instructSystemInstructionPrefix}}</tt> – <span data-i18n="help_macros_56">instruct system instruction prefix</span></li> | 72 | <li><tt>{{instructSystemInstructionPrefix}}</tt> – <span data-i18n="help_macros_56">instruct system instruction prefix</span></li> |
| 73 | <li><tt>{{instructUserFiller}}</tt> – <span data-i18n="help_macros_57">instruct first user message filler</span></li> | 73 | <li><tt>{{instructUserFiller}}</tt> – <span data-i18n="help_macros_57">instruct first user message filler</span></li> |
| 74 | <li><tt>{{instructStop}}</tt> – <span data-i18n="help_macros_58">instruct stop sequence</span></li> | 74 | <li><tt>{{instructStop}}</tt> – <span data-i18n="help_macros_58">instruct stop sequence</span></li> |
| 75 | <li><tt>{{instructFirstUserPrefix}}</tt> – <span data-i18n="help_macros_first_user">instruct user first input sequence</span></li> | ||
| 76 | <li><tt>{{instructLastUserPrefix}}</tt> – <span data-i18n="help_macros_last_user">instruct user last input sequence</span></li> | ||
| 75 | </ul> | 77 | </ul> |
| 76 | <div data-i18n="Chat variables Macros:"> | 78 | <div data-i18n="Chat variables Macros:"> |
| 77 | Chat variables Macros: | 79 | Chat variables Macros: |