Merge pull request #3701 from bmen25124/exports_for_chat_rebuild New exported methods

f245c48b170367606c1ed2063315dcb89c1e347f

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

Signed
5 files changed, +53 -23Ignore whitespace
public/scripts/instruct-mode.js+9 -6
@@ -398,23 +398,26 @@ export function formatInstructModeChat(name, mes, isUser, isNarrator, forceAvata
398/**398/**
399 * Formats instruct mode system prompt.399 * Formats instruct mode system prompt.
400 * @param {string} systemPrompt System prompt string.400 * @param {string} systemPrompt System prompt string.
401 * @param {InstructSettings} customInstruct Custom instruct mode settings.
401 * @returns {string} Formatted instruct mode system prompt.402 * @returns {string} Formatted instruct mode system prompt.
402 */403 */
403export function formatInstructModeSystemPrompt(systemPrompt) {404export function formatInstructModeSystemPrompt(systemPrompt, customInstruct = null) {
404 if (!systemPrompt) {405 if (!systemPrompt) {
405 return '';406 return '';
406 }407 }
407408
408 const separator = power_user.instruct.wrap ? '\n' : '';409 const instruct = structuredClone(customInstruct ?? power_user.instruct);
410
411 const separator = instruct.wrap ? '\n' : '';
409412
410 if (power_user.instruct.system_sequence_prefix) {413 if (instruct.system_sequence_prefix) {
411 // TODO: Replace with a proper 'System' prompt entity name input414 // TODO: Replace with a proper 'System' prompt entity name input
412 const prefix = power_user.instruct.system_sequence_prefix.replace(/{{name}}/gi, 'System');415 const prefix = instruct.system_sequence_prefix.replace(/{{name}}/gi, 'System');
413 systemPrompt = prefix + separator + systemPrompt;416 systemPrompt = prefix + separator + systemPrompt;
414 }417 }
415418
416 if (power_user.instruct.system_sequence_suffix) {419 if (instruct.system_sequence_suffix) {
417 systemPrompt = systemPrompt + separator + power_user.instruct.system_sequence_suffix;420 systemPrompt = systemPrompt + separator + instruct.system_sequence_suffix;
418 }421 }
419422
420 return systemPrompt;423 return systemPrompt;
public/scripts/openai.js+7 -5
@@ -705,16 +705,18 @@ export function parseExampleIntoIndividual(messageExampleString, appendNamesForG
705 return result;705 return result;
706}706}
707707
708function formatWorldInfo(value) {708export function formatWorldInfo(value, { wiFormat = null } = {}) {
709 if (!value) {709 if (!value) {
710 return '';710 return '';
711 }711 }
712712
713 if (!oai_settings.wi_format.trim()) {713 const format = wiFormat ?? oai_settings.wi_format;
714
715 if (!format.trim()) {
714 return value;716 return value;
715 }717 }
716718
717 return stringFormat(oai_settings.wi_format, value);719 return stringFormat(format, value);
718}720}
719721
720/**722/**
@@ -952,7 +954,7 @@ async function populateDialogueExamples(prompts, chatCompletion, messageExamples
952 * @param {number} position - Prompt position in the extensions object.954 * @param {number} position - Prompt position in the extensions object.
953 * @returns {string|false} - The prompt position for prompt collection.955 * @returns {string|false} - The prompt position for prompt collection.
954 */956 */
955function getPromptPosition(position) {957export function getPromptPosition(position) {
956 if (position == extension_prompt_types.BEFORE_PROMPT) {958 if (position == extension_prompt_types.BEFORE_PROMPT) {
957 return 'start';959 return 'start';
958 }960 }
@@ -969,7 +971,7 @@ function getPromptPosition(position) {
969 * @param {number} role Role of the prompt.971 * @param {number} role Role of the prompt.
970 * @returns {string} Mapped role.972 * @returns {string} Mapped role.
971 */973 */
972function getPromptRole(role) {974export function getPromptRole(role) {
973 switch (role) {975 switch (role) {
974 case extension_prompt_roles.SYSTEM:976 case extension_prompt_roles.SYSTEM:
975 return 'system';977 return 'system';
public/scripts/power-user.js+10 -4
@@ -1985,15 +1985,21 @@ export function fuzzySearchGroups(searchValue, fuzzySearchCaches = null) {
1985/**1985/**
1986 * Renders a story string template with the given parameters.1986 * Renders a story string template with the given parameters.
1987 * @param {object} params Template parameters.1987 * @param {object} params Template parameters.
1988 * @param {object} [options] Additional options.
1989 * @param {string} [options.customStoryString] Custom story string template.
1990 * @param {InstructSettings} [options.customInstructSettings] Custom instruct settings.
1988 * @returns {string} The rendered story string.1991 * @returns {string} The rendered story string.
1989 */1992 */
1990export function renderStoryString(params) {1993export function renderStoryString(params, { customStoryString = null, customInstructSettings = null } = {}) {
1991 try {1994 try {
1995 const storyString = customStoryString ?? power_user.context.story_string;
1996 const instructSettings = structuredClone(customInstructSettings ?? power_user.instruct);
1997
1992 // Validate and log possible warnings/errors1998 // Validate and log possible warnings/errors
1993 validateStoryString(power_user.context.story_string, params);1999 validateStoryString(storyString, params);
19942000
1995 // compile the story string template into a function, with no HTML escaping2001 // compile the story string template into a function, with no HTML escaping
1996 const compiledTemplate = Handlebars.compile(power_user.context.story_string, { noEscape: true });2002 const compiledTemplate = Handlebars.compile(storyString, { noEscape: true });
19972003
1998 // render the story string template with the given params2004 // render the story string template with the given params
1999 let output = compiledTemplate(params);2005 let output = compiledTemplate(params);
@@ -2006,7 +2012,7 @@ export function renderStoryString(params) {
20062012
2007 // add a newline to the end of the story string if it doesn't have one2013 // add a newline to the end of the story string if it doesn't have one
2008 if (output.length > 0 && !output.endsWith('\n')) {2014 if (output.length > 0 && !output.endsWith('\n')) {
2009 if (!power_user.instruct.enabled || power_user.instruct.wrap) {2015 if (!instructSettings.enabled || instructSettings.wrap) {
2010 output += '\n';2016 output += '\n';
2011 }2017 }
2012 }2018 }
public/scripts/st-context.js+4 -1
@@ -49,6 +49,7 @@ import {
49 clearChat,49 clearChat,
50 unshallowCharacter,50 unshallowCharacter,
51 deleteLastMessage,51 deleteLastMessage,
52 getCharacterCardFields,
52} from '../script.js';53} from '../script.js';
53import {54import {
54 extension_settings,55 extension_settings,
@@ -78,7 +79,7 @@ import { ToolManager } from './tool-calling.js';
78import { accountStorage } from './util/AccountStorage.js';79import { accountStorage } from './util/AccountStorage.js';
79import { timestampToMoment, uuidv4 } from './utils.js';80import { timestampToMoment, uuidv4 } from './utils.js';
80import { getGlobalVariable, getLocalVariable, setGlobalVariable, setLocalVariable } from './variables.js';81import { getGlobalVariable, getLocalVariable, setGlobalVariable, setLocalVariable } from './variables.js';
81import { convertCharacterBook, loadWorldInfo, saveWorldInfo, updateWorldInfoList } from './world-info.js';82import { convertCharacterBook, getWorldInfoPrompt, loadWorldInfo, saveWorldInfo, updateWorldInfoList } from './world-info.js';
82import { ChatCompletionService, TextCompletionService } from './custom-request.js';83import { ChatCompletionService, TextCompletionService } from './custom-request.js';
83import { ConnectionManagerRequestService } from './extensions/shared.js';84import { ConnectionManagerRequestService } from './extensions/shared.js';
84import { updateReasoningUI, parseReasoningFromString } from './reasoning.js';85import { updateReasoningUI, parseReasoningFromString } from './reasoning.js';
@@ -189,6 +190,7 @@ export function getContext() {
189 textCompletionSettings: textgenerationwebui_settings,190 textCompletionSettings: textgenerationwebui_settings,
190 powerUserSettings: power_user,191 powerUserSettings: power_user,
191 getCharacters,192 getCharacters,
193 getCharacterCardFields,
192 uuidv4,194 uuidv4,
193 humanizedDateTime,195 humanizedDateTime,
194 updateMessageBlock,196 updateMessageBlock,
@@ -207,6 +209,7 @@ export function getContext() {
207 saveWorldInfo,209 saveWorldInfo,
208 updateWorldInfoList,210 updateWorldInfoList,
209 convertCharacterBook,211 convertCharacterBook,
212 getWorldInfoPrompt,
210 CONNECT_API_MAP,213 CONNECT_API_MAP,
211 getTextGenServer,214 getTextGenServer,
212 extractMessageFromData,215 extractMessageFromData,
public/scripts/world-info.js+23 -7
@@ -753,10 +753,17 @@ export const worldInfoCache = new StructuredCloneMap({ cloneOnGet: true, cloneOn
753753
754/**754/**
755 * Gets the world info based on chat messages.755 * Gets the world info based on chat messages.
756 * @param {string[]} chat The chat messages to scan, in reverse order.756 * @param {string[]} chat - The chat messages to scan, in reverse order.
757 * @param {number} maxContext The maximum context size of the generation.757 * @param {number} maxContext - The maximum context size of the generation.
758 * @param {boolean} isDryRun If true, the function will not emit any events.758 * @param {boolean} isDryRun - If true, the function will not emit any events.
759 * @typedef {{worldInfoString: string, worldInfoBefore: string, worldInfoAfter: string, worldInfoExamples: any[], worldInfoDepth: any[]}} WIPromptResult759 * @typedef {object} WIPromptResult
760 * @property {string} worldInfoString - Complete world info string
761 * @property {string} worldInfoBefore - World info that goes before the prompt
762 * @property {string} worldInfoAfter - World info that goes after the prompt
763 * @property {Array} worldInfoExamples - Array of example entries
764 * @property {Array} worldInfoDepth - Array of depth entries
765 * @property {Array} anBefore - Array of entries before Author's Note
766 * @property {Array} anAfter - Array of entries after Author's Note
760 * @returns {Promise<WIPromptResult>} The world info string and depth.767 * @returns {Promise<WIPromptResult>} The world info string and depth.
761 */768 */
762export async function getWorldInfoPrompt(chat, maxContext, isDryRun) {769export async function getWorldInfoPrompt(chat, maxContext, isDryRun) {
@@ -778,6 +785,8 @@ export async function getWorldInfoPrompt(chat, maxContext, isDryRun) {
778 worldInfoAfter,785 worldInfoAfter,
779 worldInfoExamples: activatedWorldInfo.EMEntries ?? [],786 worldInfoExamples: activatedWorldInfo.EMEntries ?? [],
780 worldInfoDepth: activatedWorldInfo.WIDepthEntries ?? [],787 worldInfoDepth: activatedWorldInfo.WIDepthEntries ?? [],
788 anBefore: activatedWorldInfo.ANBeforeEntries ?? [],
789 anAfter: activatedWorldInfo.ANAfterEntries ?? [],
781 };790 };
782}791}
783792
@@ -3862,7 +3871,14 @@ function parseDecorators(content) {
3862 * @param {string[]} chat The chat messages to scan, in reverse order.3871 * @param {string[]} chat The chat messages to scan, in reverse order.
3863 * @param {number} maxContext The maximum context size of the generation.3872 * @param {number} maxContext The maximum context size of the generation.
3864 * @param {boolean} isDryRun Whether to perform a dry run.3873 * @param {boolean} isDryRun Whether to perform a dry run.
3865 * @typedef {{ worldInfoBefore: string, worldInfoAfter: string, EMEntries: any[], WIDepthEntries: any[], allActivatedEntries: Set<any> }} WIActivated3874 * @typedef {object} WIActivated
3875 * @property {string} worldInfoBefore The world info before the chat.
3876 * @property {string} worldInfoAfter The world info after the chat.
3877 * @property {any[]} EMEntries The entries for examples.
3878 * @property {any[]} WIDepthEntries The depth entries.
3879 * @property {any[]} ANBeforeEntries The entries before Author's Note.
3880 * @property {any[]} ANAfterEntries The entries after Author's Note.
3881 * @property {Set<any>} allActivatedEntries All entries.
3866 * @returns {Promise<WIActivated>} The world info activated.3882 * @returns {Promise<WIActivated>} The world info activated.
3867 */3883 */
3868export async function checkWorldInfo(chat, maxContext, isDryRun) {3884export async function checkWorldInfo(chat, maxContext, isDryRun) {
@@ -3906,7 +3922,7 @@ export async function checkWorldInfo(chat, maxContext, isDryRun) {
3906 timedEffects.checkTimedEffects();3922 timedEffects.checkTimedEffects();
39073923
3908 if (sortedEntries.length === 0) {3924 if (sortedEntries.length === 0) {
3909 return { worldInfoBefore: '', worldInfoAfter: '', WIDepthEntries: [], EMEntries: [], allActivatedEntries: new Set() };3925 return { worldInfoBefore: '', worldInfoAfter: '', WIDepthEntries: [], EMEntries: [], ANBeforeEntries: [], ANAfterEntries: [], allActivatedEntries: new Set() };
3910 }3926 }
39113927
3912 /** @type {number[]} Represents the delay levels for entries that are delayed until recursion */3928 /** @type {number[]} Represents the delay levels for entries that are delayed until recursion */
@@ -4355,7 +4371,7 @@ export async function checkWorldInfo(chat, maxContext, isDryRun) {
4355 console.log(`[WI] ${isDryRun ? 'Hypothetically adding' : 'Adding'} ${allActivatedEntries.size} entries to prompt`, Array.from(allActivatedEntries.values()));4371 console.log(`[WI] ${isDryRun ? 'Hypothetically adding' : 'Adding'} ${allActivatedEntries.size} entries to prompt`, Array.from(allActivatedEntries.values()));
4356 console.debug(`[WI] --- DONE${isDryRun ? ' (DRY RUN)' : ''} ---`);4372 console.debug(`[WI] --- DONE${isDryRun ? ' (DRY RUN)' : ''} ---`);
43574373
4358 return { worldInfoBefore, worldInfoAfter, EMEntries, WIDepthEntries, allActivatedEntries: new Set(allActivatedEntries.values()) };4374 return { worldInfoBefore, worldInfoAfter, EMEntries, WIDepthEntries, ANBeforeEntries: ANTopEntries, ANAfterEntries: ANBottomEntries, allActivatedEntries: new Set(allActivatedEntries.values()) };
4359}4375}
43604376
4361/**4377/**