Merge pull request #2564 from SillyTavern/instruct-mistral-large Add first/last user messages prefixes for instruct mode

ad387a7464622bc07947592a64273b0beb47c11b

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

Signed
5 files changed, +51 -3Showing whitespace changes
public/index.html+18 -0
@@ -3297,6 +3297,24 @@
32973297 </div>
32983298 </div>
32993299 <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="&mdash;" 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="&mdash;" rows="1"></textarea>
3314+ </div>
3315+ </div>
3316+ </div>
3317+ <div class="flex-container">
33003318 <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.">
33013319 <label for="instruct_last_system_sequence">
33023320 <small data-i18n="System Instruction Prefix">System Instruction Prefix</small>
public/script.js+7 -1
@@ -3611,6 +3611,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
36113611 let chat2 = [];
36123612 let continue_mag = '';
36133613 const userMessageIndices = [];
3614+ const lastUserMessageIndex = coreChat.findLastIndex(x => x.is_user);
36143615
36153616 for (let i = coreChat.length - 1, j = 0; i >= 0; i--, j++) {
36163617 if (main_api == 'openai') {
@@ -3629,6 +3630,11 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
36293630 chat2[i] = formatMessageHistoryItem(coreChat[j], isInstruct, force_output_sequence.FIRST);
36303631 }
36313632
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+
36323638 // Do not suffix the message for continuation
36333639 if (i === 0 && isContinue) {
36343640 if (isInstruct) {
@@ -3654,7 +3660,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
36543660 mes: power_user.instruct.user_alignment_message,
36553661 is_user: true,
36563662 };
36573663 userAlignmentMessage = formatMessageHistoryItem(alignmentMessage, isInstruct, falseforce_output_sequence.FIRST);
36583664 }
36593665
36603666 // Call combined AN into Generate
public/scripts/instruct-mode.js+23 -1
@@ -34,6 +34,8 @@ const controls = [
3434 { id: 'instruct_names_force_groups', property: 'names_force_groups', isCheckbox: true },
3535 { id: 'instruct_first_output_sequence', property: 'first_output_sequence', isCheckbox: false },
3636 { 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 },
3739 { id: 'instruct_activation_regex', property: 'activation_regex', isCheckbox: false },
3840 { id: 'instruct_bind_to_context', property: 'bind_to_context', isCheckbox: true },
3941 { id: 'instruct_skip_examples', property: 'skip_examples', isCheckbox: true },
@@ -58,6 +60,8 @@ function migrateInstructModeSettings(settings) {
5860 system_suffix: '',
5961 user_alignment_message: '',
6062 last_system_sequence: '',
63+ first_input_sequence: '',
64+ last_input_sequence: '',
6165 names_force_groups: true,
6266 skip_examples: false,
6367 system_same_as_user: false,
@@ -253,7 +257,15 @@ export function getInstructStoppingSequences() {
253257 const system_sequence = power_user.instruct.system_sequence?.replace(/{{name}}/gi, 'System') || '';
254258 const last_system_sequence = power_user.instruct.last_system_sequence?.replace(/{{name}}/gi, 'System') || '';
255259
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');
257269
258270 combined_sequence.split('\n').filter((line, index, self) => self.indexOf(line) === index).forEach(addInstructSequence);
259271 }
@@ -301,6 +313,14 @@ export function formatInstructModeChat(name, mes, isUser, isNarrator, forceAvata
301313 }
302314
303315 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+
304324 return power_user.instruct.input_sequence;
305325 }
306326
@@ -552,6 +572,8 @@ export function replaceInstructMacros(input, env) {
552572 'instructStop': power_user.instruct.stop_sequence,
553573 'instructUserFiller': power_user.instruct.user_alignment_message,
554574 '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,
555577 };
556578
557579 for (const [placeholder, value] of Object.entries(instructMacros)) {
public/scripts/power-user.js+1 -1
@@ -2175,7 +2175,7 @@ function validateStoryString(storyString, params) {
21752175 validateMissingField('personality');
21762176 validateMissingField('persona');
21772177 validateMissingField('scenario');
21782178 // validateMissingField('system');
21792179 validateMissingField('wiBefore', 'loreBefore');
21802180 validateMissingField('wiAfter', 'loreAfter');
21812181
public/scripts/templates/macros.html+2 -0
@@ -72,6 +72,8 @@
7272 <li><tt>&lcub;&lcub;instructSystemInstructionPrefix&rcub;&rcub;</tt> – <span data-i18n="help_macros_56">instruct system instruction prefix</span></li>
7373 <li><tt>&lcub;&lcub;instructUserFiller&rcub;&rcub;</tt> – <span data-i18n="help_macros_57">instruct first user message filler</span></li>
7474 <li><tt>&lcub;&lcub;instructStop&rcub;&rcub;</tt> – <span data-i18n="help_macros_58">instruct stop sequence</span></li>
75+ <li><tt>&lcub;&lcub;instructFirstUserPrefix&rcub;&rcub;</tt> – <span data-i18n="help_macros_first_user">instruct user first input sequence</span></li>
76+ <li><tt>&lcub;&lcub;instructLastUserPrefix&rcub;&rcub;</tt> – <span data-i18n="help_macros_last_user">instruct user last input sequence</span></li>
7577</ul>
7678<div data-i18n="Chat variables Macros:">
7779 Chat variables Macros: