Add at-depth position for custom Prompt Manager prompts
This commit is contained in:
parent
6b5aa9d06e
commit
abb78d1d6b
|
@ -4318,23 +4318,44 @@
|
|||
<h3>Edit</h3>
|
||||
<div class="completion_prompt_manager_popup_entry">
|
||||
<form class="completion_prompt_manager_popup_entry_form">
|
||||
<div class="completion_prompt_manager_popup_entry_form_control">
|
||||
<label for="completion_prompt_manager_popup_entry_form_name">
|
||||
<span>Name</span>
|
||||
</label>
|
||||
<div class="text_muted">A name for this prompt.</div>
|
||||
<input id="completion_prompt_manager_popup_entry_form_name" class="text_pole" type="text" name="name" />
|
||||
<div class="flex-container gap10px">
|
||||
<div class="completion_prompt_manager_popup_entry_form_control flex1">
|
||||
<label for="completion_prompt_manager_popup_entry_form_name">
|
||||
<span>Name</span>
|
||||
</label>
|
||||
<div class="text_muted">A name for this prompt.</div>
|
||||
<input id="completion_prompt_manager_popup_entry_form_name" class="text_pole" type="text" name="name" />
|
||||
</div>
|
||||
<div class="completion_prompt_manager_popup_entry_form_control flex1">
|
||||
<label for="completion_prompt_manager_popup_entry_form_role">
|
||||
<span>Role</span>
|
||||
</label>
|
||||
<div class="text_muted">To whom this message will be attributed.</div>
|
||||
<select id="completion_prompt_manager_popup_entry_form_role" class="text_pole" name="role">
|
||||
<option value="system">System</option>
|
||||
<option value="user">User</option>
|
||||
<option value="assistant">AI Assistant</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="completion_prompt_manager_popup_entry_form_control">
|
||||
<label for="completion_prompt_manager_popup_entry_form_role">
|
||||
<span>Role</span>
|
||||
</label>
|
||||
<div class="text_muted">To whom this message will be attributed.</div>
|
||||
<select id="completion_prompt_manager_popup_entry_form_role" class="text_pole" name="role">
|
||||
<option value="system">System</option>
|
||||
<option value="user">User</option>
|
||||
<option value="assistant">AI Assistant</option>
|
||||
</select>
|
||||
<div class="flex-container gap10px">
|
||||
<div class="completion_prompt_manager_popup_entry_form_control flex1">
|
||||
<label for="completion_prompt_manager_popup_entry_form_injection_position">
|
||||
<span>Position</span>
|
||||
</label>
|
||||
<div class="text_muted">Injection position. Next to other prompts (relative) or in-chat (absolute).</div>
|
||||
<select id="completion_prompt_manager_popup_entry_form_injection_position" class="text_pole" name="injection_position">
|
||||
<option value="0">Relative</option>
|
||||
<option value="1">Absolute</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="completion_prompt_manager_popup_entry_form_control flex1">
|
||||
<label for="completion_prompt_manager_popup_entry_form_injection_depth">
|
||||
<span>Depth</span>
|
||||
</label>
|
||||
<div class="text_muted">Injection depth. 0 = after the last message, 1 = before the last message, etc.</div>
|
||||
<input id="completion_prompt_manager_popup_entry_form_injection_depth" class="text_pole" type="number" name="injection_depth" min="0" max="999" value="4" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="completion_prompt_manager_popup_entry_form_control">
|
||||
<label for="completion_prompt_manager_popup_entry_form_prompt">
|
||||
|
|
|
@ -21,6 +21,16 @@ function debouncePromise(func, delay) {
|
|||
};
|
||||
}
|
||||
|
||||
const DEFAULT_DEPTH = 4;
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
export const INJECTION_POSITION ={
|
||||
RELATIVE: 0,
|
||||
ABSOLUTE: 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* Register migrations for the prompt manager when settings are loaded or an Open AI preset is loaded.
|
||||
*/
|
||||
|
@ -60,7 +70,7 @@ const registerPromptManagerMigration = () => {
|
|||
* Represents a prompt.
|
||||
*/
|
||||
class Prompt {
|
||||
identifier; role; content; name; system_prompt; position;
|
||||
identifier; role; content; name; system_prompt; position; injection_position; injection_depth;
|
||||
|
||||
/**
|
||||
* Create a new Prompt instance.
|
||||
|
@ -72,14 +82,18 @@ class Prompt {
|
|||
* @param {string} param0.name - The name of the prompt.
|
||||
* @param {boolean} param0.system_prompt - Indicates if the prompt is a system prompt.
|
||||
* @param {string} param0.position - The position of the prompt in the prompt list.
|
||||
* @param {number} param0.injection_position - The insert position of the prompt.
|
||||
* @param {number} param0.injection_depth - The depth of the prompt in the chat.
|
||||
*/
|
||||
constructor({ identifier, role, content, name, system_prompt, position } = {}) {
|
||||
constructor({ identifier, role, content, name, system_prompt, position, injection_depth, injection_position } = {}) {
|
||||
this.identifier = identifier;
|
||||
this.role = role;
|
||||
this.content = content;
|
||||
this.name = name;
|
||||
this.system_prompt = system_prompt;
|
||||
this.position = position;
|
||||
this.injection_depth = injection_depth;
|
||||
this.injection_position = injection_position;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,6 +395,8 @@ PromptManagerModule.prototype.init = function (moduleConfiguration, serviceSetti
|
|||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name').value = prompt.name;
|
||||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role').value = 'system';
|
||||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value = prompt.content;
|
||||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').value = prompt.injection_position ?? 0;
|
||||
document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth').value = prompt.injection_depth ?? DEFAULT_DEPTH;
|
||||
}
|
||||
|
||||
// Append prompt to selected character
|
||||
|
@ -673,6 +689,8 @@ PromptManagerModule.prototype.updatePromptWithPromptEditForm = function (prompt)
|
|||
prompt.name = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name').value;
|
||||
prompt.role = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role').value;
|
||||
prompt.content = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt').value;
|
||||
prompt.injection_position = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position').value);
|
||||
prompt.injection_depth = Number(document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth').value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1085,10 +1103,14 @@ PromptManagerModule.prototype.loadPromptIntoEditForm = function (prompt) {
|
|||
const nameField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name');
|
||||
const roleField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role');
|
||||
const promptField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt');
|
||||
const injectionPositionField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position');
|
||||
const injectionDepthField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth');
|
||||
|
||||
nameField.value = prompt.name ?? '';
|
||||
roleField.value = prompt.role ?? '';
|
||||
promptField.value = prompt.content ?? '';
|
||||
injectionPositionField.value = prompt.injection_position ?? INJECTION_POSITION.RELATIVE;
|
||||
injectionDepthField.value = prompt.injection_depth ?? DEFAULT_DEPTH;
|
||||
|
||||
const resetPromptButton = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_reset');
|
||||
if (true === prompt.system_prompt) {
|
||||
|
@ -1152,10 +1174,14 @@ PromptManagerModule.prototype.clearEditForm = function () {
|
|||
const nameField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_name');
|
||||
const roleField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_role');
|
||||
const promptField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_prompt');
|
||||
const injectionPositionField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_position');
|
||||
const injectionDepthField = document.getElementById(this.configuration.prefix + 'prompt_manager_popup_entry_form_injection_depth');
|
||||
|
||||
nameField.value = '';
|
||||
roleField.selectedIndex = 0;
|
||||
promptField.value = '';
|
||||
injectionPositionField.selectedIndex = 0;
|
||||
injectionDepthField.value = DEFAULT_DEPTH;
|
||||
|
||||
roleField.disabled = false;
|
||||
}
|
||||
|
@ -1435,13 +1461,18 @@ PromptManagerModule.prototype.renderPromptManagerListItems = function () {
|
|||
}
|
||||
|
||||
const encodedName = escapeHtml(prompt.name);
|
||||
const isSystemPrompt = !prompt.marker && prompt.system_prompt && prompt.injection_position !== INJECTION_POSITION.ABSOLUTE;
|
||||
const isUserPrompt = !prompt.marker && !prompt.system_prompt && prompt.injection_position !== INJECTION_POSITION.ABSOLUTE;
|
||||
const isInjectionPrompt = !prompt.marker && prompt.injection_position === INJECTION_POSITION.ABSOLUTE;
|
||||
listItemHtml += `
|
||||
<li class="${prefix}prompt_manager_prompt ${draggableClass} ${enabledClass} ${markerClass}" data-pm-identifier="${prompt.identifier}">
|
||||
<span class="${prefix}prompt_manager_prompt_name" data-pm-name="${encodedName}">
|
||||
${prompt.marker ? '<span class="fa-solid fa-thumb-tack" title="Marker"></span>' : ''}
|
||||
${!prompt.marker && prompt.system_prompt ? '<span class="fa-solid fa-square-poll-horizontal" title="Global Prompt"></span>' : ''}
|
||||
${!prompt.marker && !prompt.system_prompt ? '<span class="fa-solid fa-user" title="User Prompt"></span>' : ''}
|
||||
${isSystemPrompt ? '<span class="fa-solid fa-square-poll-horizontal" title="Global Prompt"></span>' : ''}
|
||||
${isUserPrompt ? '<span class="fa-solid fa-user" title="User Prompt"></span>' : ''}
|
||||
${isInjectionPrompt ? `<span class="fa-solid fa-syringe" title="In-Chat Injection"></span>` : ''}
|
||||
${this.isPromptInspectionAllowed(prompt) ? `<a class="prompt-manager-inspect-action">${encodedName}</a>` : encodedName}
|
||||
${isInjectionPrompt ? `<small class="prompt-manager-injection-depth">@ ${prompt.injection_depth}</small>` : ''}
|
||||
</span>
|
||||
<span>
|
||||
<span class="prompt_manager_prompt_controls">
|
||||
|
|
|
@ -31,7 +31,8 @@ import { groups, selected_group } from "./group-chats.js";
|
|||
import {
|
||||
promptManagerDefaultPromptOrders,
|
||||
chatCompletionDefaultPrompts, Prompt,
|
||||
PromptManagerModule as PromptManager
|
||||
PromptManagerModule as PromptManager,
|
||||
INJECTION_POSITION,
|
||||
} from "./PromptManager.js";
|
||||
|
||||
import {
|
||||
|
@ -321,15 +322,6 @@ function setOpenAIMessages(chat) {
|
|||
openai_msgs[i] = { "role": role, "content": content, name: name };
|
||||
j++;
|
||||
}
|
||||
|
||||
// Add chat injections, 100 = maximum depth of injection. (Why would you ever need more?)
|
||||
for (let i = MAX_INJECTION_DEPTH; i >= 0; i--) {
|
||||
const anchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, i);
|
||||
|
||||
if (anchor && anchor.length) {
|
||||
openai_msgs.splice(i, 0, { "role": 'system', 'content': anchor.trim() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setOpenAIMessageExamples(mesExamplesArray) {
|
||||
|
@ -468,6 +460,34 @@ function formatWorldInfo(value) {
|
|||
return stringFormat(oai_settings.wi_format, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function populates the injections in the conversation.
|
||||
*
|
||||
* @param {Prompt[]} prompts - Array containing injection prompts.
|
||||
*/
|
||||
function populationInjectionPrompts(prompts) {
|
||||
for (let i = MAX_INJECTION_DEPTH; i >= 0; i--) {
|
||||
// Get prompts for current depth
|
||||
const depthPrompts = prompts.filter(prompt => prompt.injection_depth === i && prompt.content);
|
||||
|
||||
// Order of priority (most important go lower)
|
||||
const roles = ['system', 'user', 'assistant'];
|
||||
|
||||
for (const role of roles) {
|
||||
// Get prompts for current role
|
||||
const rolePrompts = depthPrompts.filter(prompt => prompt.role === role).map(x => x.content).join('\n');
|
||||
// Get extension prompt (only for system role)
|
||||
const extensionPrompt = role === 'system' ? getExtensionPrompt(extension_prompt_types.IN_CHAT, i) : '';
|
||||
|
||||
const jointPrompt = [rolePrompts, extensionPrompt].filter(x => x).map(x => x.trim()).join('\n');
|
||||
|
||||
if (jointPrompt && jointPrompt.length) {
|
||||
openai_msgs.splice(i, 0, { "role": role, 'content': jointPrompt });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the chat history of the conversation.
|
||||
*
|
||||
|
@ -477,7 +497,6 @@ function formatWorldInfo(value) {
|
|||
* @param cyclePrompt
|
||||
*/
|
||||
function populateChatHistory(prompts, chatCompletion, type = null, cyclePrompt = null) {
|
||||
// Chat History
|
||||
chatCompletion.add(new MessageCollection('chatHistory'), prompts.index('chatHistory'));
|
||||
|
||||
let names = (selected_group && groups.find(x => x.id === selected_group)?.members.map(member => characters.find(c => c.avatar === member)?.name).filter(Boolean).join(', ')) || '';
|
||||
|
@ -646,14 +665,20 @@ function populateChatCompletion(prompts, chatCompletion, { bias, quietPrompt, ty
|
|||
|
||||
// Add ordered system and user prompts
|
||||
const systemPrompts = ['nsfw', 'jailbreak'];
|
||||
const userPrompts = prompts.collection
|
||||
.filter((prompt) => false === prompt.system_prompt)
|
||||
const userRelativePrompts = prompts.collection
|
||||
.filter((prompt) => false === prompt.system_prompt && prompt.injection_position !== INJECTION_POSITION.ABSOLUTE)
|
||||
.reduce((acc, prompt) => {
|
||||
acc.push(prompt.identifier)
|
||||
return acc;
|
||||
}, []);
|
||||
const userAbsolutePrompts = prompts.collection
|
||||
.filter((prompt) => false === prompt.system_prompt && prompt.injection_position === INJECTION_POSITION.ABSOLUTE)
|
||||
.reduce((acc, prompt) => {
|
||||
acc.push(prompt)
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
[...systemPrompts, ...userPrompts].forEach(identifier => addToChatCompletion(identifier));
|
||||
[...systemPrompts, ...userRelativePrompts].forEach(identifier => addToChatCompletion(identifier));
|
||||
|
||||
// Add enhance definition instruction
|
||||
if (prompts.has('enhanceDefinitions')) addToChatCompletion('enhanceDefinitions');
|
||||
|
@ -697,6 +722,9 @@ function populateChatCompletion(prompts, chatCompletion, { bias, quietPrompt, ty
|
|||
}
|
||||
}
|
||||
|
||||
// Add in-chat injections
|
||||
populationInjectionPrompts(userAbsolutePrompts);
|
||||
|
||||
// Decide whether dialogue examples should always be added
|
||||
if (power_user.pin_examples) {
|
||||
populateDialogueExamples(prompts, chatCompletion);
|
||||
|
@ -1714,7 +1742,7 @@ class ChatCompletion {
|
|||
*
|
||||
* @param {Message} message - The message to insert.
|
||||
* @param {string} identifier - The identifier of the collection where to insert the message.
|
||||
* @param {string} position - The position at which to insert the message ('start' or 'end').
|
||||
* @param {string|number} position - The position at which to insert the message ('start' or 'end').
|
||||
*/
|
||||
insert(message, identifier, position = 'end') {
|
||||
this.validateMessage(message);
|
||||
|
@ -1723,7 +1751,8 @@ class ChatCompletion {
|
|||
const index = this.findMessageIndex(identifier);
|
||||
if (message.content) {
|
||||
if ('start' === position) this.messages.collection[index].collection.unshift(message);
|
||||
else if ('end' === position) this.messages.collection[index].collection.push(message);
|
||||
else if ('end' === position) this.messages.collection[index].collection.push(message)
|
||||
else if (typeof position === 'number') this.messages.collection[index].collection.splice(position, 0, message);
|
||||
|
||||
this.decreaseTokenBudgetBy(message.getTokens());
|
||||
|
||||
|
@ -1731,7 +1760,6 @@ class ChatCompletion {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the last item of the collection
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue