Merge pull request #3737 from qvink/staging Adding option to disable removal of "{{user}}:" and "{{char}}:" in generateRaw()

97172597761c9ba026928cfc749d9efefa90390d

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

Signed
2 files changed, +106 -22Showing whitespace changes
public/script.js+100 -21
@@ -3315,11 +3315,23 @@ class StreamingProcessor {
33153315
33163316 if (!isImpersonate && !isContinue && Array.isArray(this.swipes) && this.swipes.length > 0) {
33173317 for (let i = 0; i < this.swipes.length; i++) {
33183318 this.swipes[i] = cleanUpMessage(this.swipes[i], false, false, true, this.stoppingStrings);{
3319+ getMessage: this.swipes[i],
3320+ isImpersonate: false,
3321+ isContinue: false,
3322+ displayIncompleteSentences: true,
3323+ stoppingStrings: this.stoppingStrings,
3324+ });
33193325 }
33203326 }
33213327
3322- let processedText = cleanUpMessage(text, isImpersonate, isContinue, !isFinal, this.stoppingStrings);
3328+ let processedText = cleanUpMessage({
3329+ getMessage: text,
3330+ isImpersonate: isImpersonate,
3331+ isContinue: isContinue,
3332+ displayIncompleteSentences: !isFinal,
3333+ stoppingStrings: this.stoppingStrings,
3334+ });
33233335
33243336 const charsToBalance = ['*', '"', '```'];
33253337 for (const char of charsToBalance) {
@@ -3551,9 +3563,10 @@ class StreamingProcessor {
35513563 * @param {boolean} quietToLoud true to generate a message in system mode, false to generate a message in character mode
35523564 * @param {string} [systemPrompt] System prompt to use. Only Instruct mode or OpenAI.
35533565 * @param {number} [responseLength] Maximum response length. If unset, the global default value is used.
3566+ * @param {boolean} [trimNames] Whether to allow trimming "{{user}}:" and "{{char}}:" from the response.
35543567 * @returns {Promise<string>} Generated message
35553568 */
35563569export async function generateRaw(prompt, api, instructOverride, quietToLoud, systemPrompt, responseLength, trimNames = true) {
35573570 if (!api) {
35583571 api = main_api;
35593572 }
@@ -3643,7 +3656,15 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
36433656 }
36443657
36453658 // format result, exclude user prompt bias
3646- const message = cleanUpMessage(extractMessageFromData(data), false, false, true, null, false);
3659+ const message = cleanUpMessage({
3660+ getMessage: extractMessageFromData(data),
3661+ isImpersonate: false,
3662+ isContinue: false,
3663+ displayIncompleteSentences: true,
3664+ includeUserPromptBias: false,
3665+ trimNames: trimNames,
3666+ trimWrongNames: trimNames,
3667+ });
36473668
36483669 if (!message) {
36493670 throw new Error('No message generated');
@@ -4844,7 +4865,12 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
48444865
48454866 hideSwipeButtons();
48464867 let getMessage = await streamingProcessor.generate();
48474868 let messageChunk = cleanUpMessage(getMessage, isImpersonate, isContinue, false);{
4869+ getMessage: getMessage,
4870+ isImpersonate: isImpersonate,
4871+ isContinue: isContinue,
4872+ displayIncompleteSentences: false,
4873+ });
48484874
48494875 if (isContinue) {
48504876 getMessage = continue_mag + getMessage;
@@ -4928,7 +4954,14 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
49284954
49294955 const swipes = extractMultiSwipes(data, type);
49304956
49314957 messageChunk = cleanUpMessage(getMessage, isImpersonate, isContinue, false);{
4958+ getMessage: getMessage,
4959+ isImpersonate: isImpersonate,
4960+ isContinue: isContinue,
4961+ displayIncompleteSentences: false,
4962+ });
4963+
4964+
49324965 reasoning = getRegexedString(reasoning, regex_placement.REASONING);
49334966
49344967 if (power_user.trim_spaces) {
@@ -4942,7 +4975,12 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
49424975
49434976 //Formating
49444977 const displayIncomplete = type === 'quiet' && !quietToLoud;
49454978 getMessage = cleanUpMessage(getMessage, isImpersonate, isContinue, displayIncomplete);{
4979+ getMessage: getMessage,
4980+ isImpersonate: isImpersonate,
4981+ isContinue: isContinue,
4982+ displayIncompleteSentences: displayIncomplete,
4983+ });
49464984
49474985 if (isImpersonate) {
49484986 $('#send_textarea').val(getMessage)[0].dispatchEvent(new Event('input', { bubbles: true }));
@@ -5908,7 +5946,13 @@ function extractMultiSwipes(data, type) {
59085946
59095947 for (let i = 1; i < data.choices.length; i++) {
59105948 const text = data?.choices[i]?.message?.content ?? data?.choices[i]?.text ?? '';
59115949 const cleanedText = cleanUpMessage(text, false, false, false);{
5950+ getMessage: text,
5951+ isImpersonate: false,
5952+ isContinue: false,
5953+ displayIncompleteSentences: false,
5954+ });
5955+
59125956 swipes.push(cleanedText);
59135957 }
59145958 }
@@ -5916,7 +5960,26 @@ function extractMultiSwipes(data, type) {
59165960 return swipes;
59175961}
59185962
5919-export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayIncompleteSentences = false, stoppingStrings = null, includeUserPromptBias = true) {
5963+/**
5964+ * Formats a message according to user settings
5965+ * @param {object} [options] - Additional options.
5966+ * @param {string} [options.getMessage] The message to clean up
5967+ * @param {boolean} [options.isImpersonate] Whether this is an impersonated message
5968+ * @param {boolean} [options.isContinue] Whether this is a continued message
5969+ * @param {boolean} [options.displayIncompleteSentences] Whether to keep incomplete sentences at the end.
5970+ * @param {array} [options.stoppingStrings] Array of stopping strings.
5971+ * @param {boolean} [options.includeUserPromptBias] Whether to permit prepending the user prompt bias at the beginning.
5972+ * @param {boolean} [options.trimNames] Whether to allow trimming "{{char}}:" or "{{user}}:" from the beginning.
5973+ * @param {boolean} [options.trimWrongNames] Whether to allow deleting responses prefixed by the incorrect name, depending on isImpersonate
5974+ *
5975+ * @returns {string} The formatted message
5976+ */
5977+export function cleanUpMessage({ getMessage, isImpersonate, isContinue, displayIncompleteSentences = false, stoppingStrings = null, includeUserPromptBias = true, trimNames = true, trimWrongNames = true } = {}) {
5978+ if (arguments.length > 0 && typeof arguments[0] !== 'object') {
5979+ console.trace('cleanUpMessage called with positional arguments. Please use an object instead.');
5980+ [getMessage, isImpersonate, isContinue, displayIncompleteSentences, stoppingStrings, includeUserPromptBias, trimNames, trimWrongNames] = arguments;
5981+ }
5982+
59205983 if (!getMessage) {
59215984 return '';
59225985 }
@@ -5961,21 +6024,32 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc
59616024 // "trailing whitespace on newlines\nevery line of the string\nsample text"
59626025 getMessage = getMessage.replace(/[^\S\r\n]+$/gm, '');
59636026
5964- let nameToTrim = isImpersonate ? name2 : name1;
6027+ if (trimWrongNames) {
6028+ // If this is an impersonation, delete the entire response if it starts with "{{char}}:"
6029+ // If this isn't an impersonation, delete the entire response if it starts with "{{user}}:"
6030+ // Also delete any trailing text that starts with the wrong name.
6031+ // This only occurs if the corresponding "power_user.allow_nameX_display" is false.
59656032
5966- if (isImpersonate) {
6033+ let wrongName = isImpersonate
5967- nameToTrim = power_user.allow_name2_display ? '' : name2;
6034+ ? (!power_user.allow_name2_display ? name2 : '') // char
5968- }
6035+ : (!power_user.allow_name1_display ? name1 : ''); // user
5969- else {
6036+
5970- nameToTrim = power_user.allow_name1_display ? '' : name1;
6037+ if (wrongName) {
6038+ // If the message starts with the wrong name, delete the entire response
6039+ let startIndex = getMessage.indexOf(`${wrongName}:`);
6040+ if (startIndex === 0) {
6041+ getMessage = '';
6042+ console.debug(`Message started with the wrong name: "${wrongName}" - response was deleted.`);
59716043 }
59726044
5973- if (nameToTrim && getMessage.indexOf(`${nameToTrim}:`) == 0) {
6045+ // If there is trailing text starting with the wrong name, trim it off.
59746046 getMessage startIndex = getMessage.substring(0, getMessage.indexOf(`\n${nameToTrimwrongName}:`));
6047+ if (startIndex >= 0) {
6048+ getMessage = getMessage.substring(0, startIndex);
59756049 }
5976- if (nameToTrim && getMessage.indexOf(`\n${nameToTrim}:`) >= 0) {
5977- getMessage = getMessage.substring(0, getMessage.indexOf(`\n${nameToTrim}:`));
59786050 }
6051+ }
6052+
59796053 if (getMessage.indexOf('<|endoftext|>') != -1) {
59806054 getMessage = getMessage.substring(0, getMessage.indexOf('<|endoftext|>'));
59816055 }
@@ -6035,14 +6109,19 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc
60356109 getMessage = fixMarkdown(getMessage, false);
60366110 }
60376111
6112+ if (trimNames) {
6113+ // If this is an impersonation, trim "{{user}}:" from the beginning
6114+ // If this isn't an impersonation, trim "{{char}}:" from the beginning.
6115+ // Only applied when the corresponding "power_user.allow_nameX_display" is false.
60386116 const nameToTrim2 = isImpersonate
60396117 ? (!power_user.allow_name1_display ? name1 : '') // user
60406118 : (!power_user.allow_name2_display ? name2 : ''); // char
60416119
60426120 if (nameToTrim2 && getMessage.startsWith(nameToTrim2 + ':')) {
60436121 getMessage = getMessage.replace(nameToTrim2 + ':', '');
60446122 getMessage = getMessage.trimStart();
60456123 }
6124+ }
60466125
60476126 if (isImpersonate) {
60486127 getMessage = getMessage.trim();
public/scripts/logprobs.js+6 -1
@@ -368,7 +368,12 @@ function onToggleLogprobsPanel() {
368368function createSwipe(messageId, prompt) {
369369 // need to call `cleanUpMessage` on our new prompt, because we were working
370370 // with raw model output and our new prompt is missing trimming/macro replacements
371371 const cleanedPrompt = cleanUpMessage(prompt, false, false, true);{
372+ getMessage: prompt,
373+ isImpersonate: false,
374+ isContinue: false,
375+ displayIncompleteSentences: true,
376+ });
372377
373378 const msg = chat[messageId];
374379 const newSwipeInfo = {