Merge pull request #3150 from Succubyss/getpromptentry add /getpromptentry command

f5f60e269ec7c1aa030ad2a75524ba40c668db01

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

Signed
2 files changed, +115 -6Showing whitespace changes
public/scripts/openai.js+2 -2
@@ -379,8 +379,8 @@ export let selected_proxy = proxies[0];
379let openai_setting_names;379let openai_setting_names;
380let openai_settings;380let openai_settings;
381381
382382/** @type {import('./PromptManager.js').PromptManager} */
383let promptManager = null;383export let promptManager = null;
384384
385async function validateReverseProxy() {385async function validateReverseProxy() {
386 if (!oai_settings.reverse_proxy) {386 if (!oai_settings.reverse_proxy) {
public/scripts/slash-commands.js+113 -4
@@ -52,7 +52,7 @@ import { hideChatMessageRange } from './chats.js';
52import { getContext, saveMetadataDebounced } from './extensions.js';52import { getContext, saveMetadataDebounced } from './extensions.js';
53import { getRegexedString, regex_placement } from './extensions/regex/engine.js';53import { getRegexedString, regex_placement } from './extensions/regex/engine.js';
54import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js';54import { findGroupMemberId, groups, is_group_generating, openGroupById, resetSelectedGroup, saveGroupChat, selected_group } from './group-chats.js';
55import { chat_completion_sources, oai_settings, setupChatCompletionPromptManager } from './openai.js';55import { chat_completion_sources, oai_settings, promptManager } from './openai.js';
56import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js';56import { autoSelectPersona, retriggerFirstMessageOnEmptyChat, setPersonaLockState, togglePersonaLock, user_avatar } from './personas.js';
57import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';57import { addEphemeralStoppingString, chat_styles, flushEphemeralStoppingStrings, power_user } from './power-user.js';
58import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js';58import { SERVER_INPUTS, textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
@@ -1699,6 +1699,49 @@ export function initDefaultSlashCommands() {
1699 helpString: 'Sets the model for the current API. Gets the current model name if no argument is provided.',1699 helpString: 'Sets the model for the current API. Gets the current model name if no argument is provided.',
1700 }));1700 }));
1701 SlashCommandParser.addCommandObject(SlashCommand.fromProps({1701 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
1702 name: 'getpromptentry',
1703 aliases: ['getpromptentries'],
1704 callback: getPromptEntryCallback,
1705 returns: 'true/false state of prompt(s)',
1706 namedArgumentList: [
1707 SlashCommandNamedArgument.fromProps({
1708 name: 'identifier',
1709 description: 'Prompt entry identifier(s) to retrieve',
1710 typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST],
1711 acceptsMultiple: true,
1712 enumProvider: () =>
1713 promptManager.serviceSettings.prompts
1714 .map(prompt => prompt.identifier)
1715 .map(identifier => new SlashCommandEnumValue(identifier)),
1716 }),
1717 SlashCommandNamedArgument.fromProps({
1718 name: 'name',
1719 description: 'Prompt entry name(s) to retrieve',
1720 typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST],
1721 acceptsMultiple: true,
1722 enumProvider: () =>
1723 promptManager.serviceSettings.prompts
1724 .map(prompt => prompt.name)
1725 .map(name => new SlashCommandEnumValue(name)),
1726 }),
1727 SlashCommandNamedArgument.fromProps({
1728 name: 'return',
1729 description: 'Whether the return will be simple, a list, or a dict.',
1730 typeList: [ARGUMENT_TYPE.STRING],
1731 defaultValue: 'simple',
1732 enumList: ['simple', 'list', 'dict'],
1733 }),
1734 ],
1735 helpString: `
1736 <div>
1737 Gets the state of the specified prompt entries.
1738 </div>
1739 <div>
1740 If <code>return</code> is <code>simple</code> (default) then the return will be a single value if only one value was retrieved; otherwise uses a dict (if the identifier parameter was used) or a list.
1741 </div>
1742 `,
1743 }));
1744 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
1702 name: 'setpromptentry',1745 name: 'setpromptentry',
1703 aliases: ['setpromptentries'],1746 aliases: ['setpromptentries'],
1704 callback: setPromptEntryCallback,1747 callback: setPromptEntryCallback,
@@ -1709,7 +1752,6 @@ export function initDefaultSlashCommands() {
1709 typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST],1752 typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST],
1710 acceptsMultiple: true,1753 acceptsMultiple: true,
1711 enumProvider: () => {1754 enumProvider: () => {
1712 const promptManager = setupChatCompletionPromptManager(oai_settings);
1713 const prompts = promptManager.serviceSettings.prompts;1755 const prompts = promptManager.serviceSettings.prompts;
1714 return prompts.map(prompt => new SlashCommandEnumValue(prompt.identifier, prompt.name, enumTypes.enum));1756 return prompts.map(prompt => new SlashCommandEnumValue(prompt.identifier, prompt.name, enumTypes.enum));
1715 },1757 },
@@ -1720,7 +1762,6 @@ export function initDefaultSlashCommands() {
1720 typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST],1762 typeList: [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.LIST],
1721 acceptsMultiple: true,1763 acceptsMultiple: true,
1722 enumProvider: () => {1764 enumProvider: () => {
1723 const promptManager = setupChatCompletionPromptManager(oai_settings);
1724 const prompts = promptManager.serviceSettings.prompts;1765 const prompts = promptManager.serviceSettings.prompts;
1725 return prompts.map(prompt => new SlashCommandEnumValue(prompt.name, prompt.identifier, enumTypes.enum));1766 return prompts.map(prompt => new SlashCommandEnumValue(prompt.name, prompt.identifier, enumTypes.enum));
1726 },1767 },
@@ -3787,6 +3828,75 @@ function modelCallback(args, model) {
3787}3828}
37883829
3789/**3830/**
3831 * Gets the state of prompt entries (toggles) either via identifier/uuid or name.
3832 * @param {object} args Object containing arguments
3833 * @param {string} args.identifier Select prompt entry using an identifier (uuid)
3834 * @param {string} args.name Select prompt entry using name
3835 * @param {string} args.return The type of return value to use (simple, list, dict)
3836 * @returns {Object} An object containing the states of the requested prompt entries
3837 */
3838function getPromptEntryCallback(args) {
3839 const prompts = promptManager.serviceSettings.prompts;
3840 let returnType = args.return ?? 'simple';
3841
3842 function parseArgs(arg) {
3843 // Arg is already an array
3844 if (Array.isArray(arg)) {
3845 return arg;
3846 }
3847 const list = [];
3848 try {
3849 // Arg is a JSON-stringified array
3850 const parsedArg = JSON.parse(arg);
3851 list.push(...Array.isArray(parsedArg) ? parsedArg : [arg]);
3852 } catch {
3853 // Arg is a string
3854 list.push(arg);
3855 }
3856 return list;
3857 }
3858
3859 let identifiersList = parseArgs(args.identifier);
3860 let nameList = parseArgs(args.name);
3861
3862 // Check if identifiers exists in prompt, else remove from list
3863 if (identifiersList.length !== 0) {
3864 identifiersList = identifiersList.filter(identifier => prompts.some(prompt => prompt.identifier === identifier));
3865 }
3866
3867 if (nameList.length !== 0) {
3868 nameList.forEach(name => {
3869 let identifiers = prompts
3870 .filter(entry => entry.name === name)
3871 .map(entry => entry.identifier);
3872 identifiersList = identifiersList.concat(identifiers);
3873 });
3874 }
3875
3876 // Get the state for each prompt entry
3877 let promptStates = new Map();
3878 identifiersList.forEach(identifier => {
3879 const promptOrderEntry = promptManager.getPromptOrderEntry(promptManager.activeCharacter, identifier);
3880 if (promptOrderEntry) {
3881 promptStates.set(identifier, promptOrderEntry.enabled);
3882 }
3883 });
3884
3885 // If return is simple (default) but more than one prompt state was retrieved, then change return type
3886 if (returnType === 'simple' && promptStates.size > 1) {
3887 returnType = args.identifier ? 'dict' : 'list';
3888 }
3889
3890 const result = (() => {
3891 if (returnType === 'list') return [...promptStates.values()];
3892 if (returnType === 'dict') return Object.fromEntries(promptStates);
3893 return [...promptStates.values()][0];
3894 })();
3895
3896 return result;
3897}
3898
3899/**
3790 * Sets state of prompt entries (toggles) either via identifier/uuid or name.3900 * Sets state of prompt entries (toggles) either via identifier/uuid or name.
3791 * @param {object} args Object containing arguments3901 * @param {object} args Object containing arguments
3792 * @param {string} args.identifier Select prompt entry using an identifier (uuid)3902 * @param {string} args.identifier Select prompt entry using an identifier (uuid)
@@ -3796,7 +3906,6 @@ function modelCallback(args, model) {
3796 */3906 */
3797function setPromptEntryCallback(args, targetState) {3907function setPromptEntryCallback(args, targetState) {
3798 // needs promptManager to manipulate prompt entries3908 // needs promptManager to manipulate prompt entries
3799 const promptManager = setupChatCompletionPromptManager(oai_settings);
3800 const prompts = promptManager.serviceSettings.prompts;3909 const prompts = promptManager.serviceSettings.prompts;
38013910
3802 function parseArgs(arg) {3911 function parseArgs(arg) {