mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge pull request #496 from bdashore3/dev
Character author's notes + WI individual recursion disabling
This commit is contained in:
@@ -2920,6 +2920,10 @@
|
|||||||
<input type="checkbox" name="disable" />
|
<input type="checkbox" name="disable" />
|
||||||
<span data-i18n="Disable">Disable</span>
|
<span data-i18n="Disable">Disable</span>
|
||||||
</label>
|
</label>
|
||||||
|
<label class="checkbox flex-container alignitemscenter">
|
||||||
|
<input type="checkbox" name="exclude_recursion" />
|
||||||
|
<span data-i18n="Exclude from recursion">Exclude from recursion</span>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<input class="menu_button delete_entry_button" type="submit" value="Delete Entry" />
|
<input class="menu_button delete_entry_button" type="submit" value="Delete Entry" />
|
||||||
</div>
|
</div>
|
||||||
|
@@ -50,6 +50,7 @@ const extension_settings = {
|
|||||||
memory: {},
|
memory: {},
|
||||||
note: {
|
note: {
|
||||||
default: '',
|
default: '',
|
||||||
|
chara: [],
|
||||||
},
|
},
|
||||||
caption: {},
|
caption: {},
|
||||||
expressions: {},
|
expressions: {},
|
||||||
|
@@ -2,7 +2,7 @@ import { callPopup, eventSource, event_types, getRequestHeaders, saveSettingsDeb
|
|||||||
import { dragElement, isMobile } from "../../RossAscends-mods.js";
|
import { dragElement, isMobile } from "../../RossAscends-mods.js";
|
||||||
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch } from "../../extensions.js";
|
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch } from "../../extensions.js";
|
||||||
import { power_user } from "../../power-user.js";
|
import { power_user } from "../../power-user.js";
|
||||||
import { onlyUnique, debounce } from "../../utils.js";
|
import { onlyUnique, debounce, getCharaFilename } from "../../utils.js";
|
||||||
export { MODULE_NAME };
|
export { MODULE_NAME };
|
||||||
|
|
||||||
const MODULE_NAME = 'expressions';
|
const MODULE_NAME = 'expressions';
|
||||||
@@ -437,7 +437,7 @@ function getSpriteFolderName(message) {
|
|||||||
avatarPath = message.original_avatar || context.characters.find(x => message.force_avatar && message.force_avatar.includes(encodeURIComponent(x.avatar)))?.avatar;
|
avatarPath = message.original_avatar || context.characters.find(x => message.force_avatar && message.force_avatar.includes(encodeURIComponent(x.avatar)))?.avatar;
|
||||||
}
|
}
|
||||||
else if (context.characterId) {
|
else if (context.characterId) {
|
||||||
avatarPath = context.characters[context.characterId].avatar;
|
avatarPath = getCharaFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!avatarPath) {
|
if (!avatarPath) {
|
||||||
|
@@ -9,6 +9,7 @@ import {
|
|||||||
import { selected_group } from "../../group-chats.js";
|
import { selected_group } from "../../group-chats.js";
|
||||||
import { ModuleWorkerWrapper, extension_settings, getContext, saveMetadataDebounced } from "../../extensions.js";
|
import { ModuleWorkerWrapper, extension_settings, getContext, saveMetadataDebounced } from "../../extensions.js";
|
||||||
import { registerSlashCommand } from "../../slash-commands.js";
|
import { registerSlashCommand } from "../../slash-commands.js";
|
||||||
|
import { getCharaFilename } from "../../utils.js";
|
||||||
export { MODULE_NAME };
|
export { MODULE_NAME };
|
||||||
|
|
||||||
const MODULE_NAME = '2_floating_prompt'; // <= Deliberate, for sorting lower than memory
|
const MODULE_NAME = '2_floating_prompt'; // <= Deliberate, for sorting lower than memory
|
||||||
@@ -73,7 +74,7 @@ function setNotePositionCommand(_, text) {
|
|||||||
|
|
||||||
async function onExtensionFloatingPromptInput() {
|
async function onExtensionFloatingPromptInput() {
|
||||||
chat_metadata[metadata_keys.prompt] = $(this).val();
|
chat_metadata[metadata_keys.prompt] = $(this).val();
|
||||||
$('#extension_floating_prompt_token_counter').text(getTokenCount(chat_metadata[metadata_keys.prompt]));
|
debounce(() => $('#extension_floating_prompt_token_counter').text(getTokenCount(chat_metadata[metadata_keys.prompt])), 1000);
|
||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,9 +100,66 @@ async function onExtensionFloatingPositionInput(e) {
|
|||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onExtensionFloatingCharaPromptInput() {
|
||||||
|
const tempPrompt = $(this).val();
|
||||||
|
const avatarName = getCharaFilename();
|
||||||
|
let tempCharaNote = {
|
||||||
|
name: avatarName,
|
||||||
|
prompt: tempPrompt
|
||||||
|
}
|
||||||
|
|
||||||
|
debounce(() => $('#extension_floating_chara_token_counter').text(getTokenCount(tempPrompt)), 1000);
|
||||||
|
|
||||||
|
let existingCharaNoteIndex;
|
||||||
|
let existingCharaNote;
|
||||||
|
|
||||||
|
if (extension_settings.note.chara) {
|
||||||
|
existingCharaNoteIndex = extension_settings.note.chara.findIndex((e) => e.name === avatarName);
|
||||||
|
existingCharaNote = extension_settings.note.chara[existingCharaNoteIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempPrompt.length === 0 &&
|
||||||
|
extension_settings.note.chara &&
|
||||||
|
existingCharaNote &&
|
||||||
|
!existingCharaNote.useChara
|
||||||
|
) {
|
||||||
|
extension_settings.note.chara.splice(existingCharaNoteIndex, 1);
|
||||||
|
}
|
||||||
|
else if (extension_settings.note.chara && existingCharaNote) {
|
||||||
|
Object.assign(existingCharaNote, tempCharaNote);
|
||||||
|
}
|
||||||
|
else if (avatarName && tempPrompt.length > 0) {
|
||||||
|
if (!extension_settings.note.chara) {
|
||||||
|
extension_settings.note.chara = []
|
||||||
|
}
|
||||||
|
Object.assign(tempCharaNote, { useChara: false })
|
||||||
|
|
||||||
|
extension_settings.note.chara.push(tempCharaNote);
|
||||||
|
} else {
|
||||||
|
console.log("Character author's note error: No avatar name key could be found.");
|
||||||
|
toastr.error("Something went wrong. Could not save character's author's note.");
|
||||||
|
|
||||||
|
// Don't save settings if something went wrong
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onExtensionFloatingCharaCheckboxChanged() {
|
||||||
|
const value = !!$(this).prop('checked');
|
||||||
|
const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());
|
||||||
|
|
||||||
|
if (charaNote) {
|
||||||
|
charaNote.useChara = value;
|
||||||
|
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onExtensionFloatingDefaultInput() {
|
function onExtensionFloatingDefaultInput() {
|
||||||
extension_settings.note.default = $(this).val();
|
extension_settings.note.default = $(this).val();
|
||||||
$('#extension_floating_default_token_counter').text(getTokenCount(extension_settings.note.default));
|
debounce(() => $('#extension_floating_default_token_counter').text(getTokenCount(extension_settings.note.default)), 1000);
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +172,14 @@ function loadSettings() {
|
|||||||
$('#extension_floating_interval').val(chat_metadata[metadata_keys.interval]);
|
$('#extension_floating_interval').val(chat_metadata[metadata_keys.interval]);
|
||||||
$('#extension_floating_depth').val(chat_metadata[metadata_keys.depth]);
|
$('#extension_floating_depth').val(chat_metadata[metadata_keys.depth]);
|
||||||
$(`input[name="extension_floating_position"][value="${chat_metadata[metadata_keys.position]}"]`).prop('checked', true);
|
$(`input[name="extension_floating_position"][value="${chat_metadata[metadata_keys.position]}"]`).prop('checked', true);
|
||||||
|
|
||||||
|
if (extension_settings.note.chara) {
|
||||||
|
const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());
|
||||||
|
|
||||||
|
$('#extension_floating_chara').val(charaNote ? charaNote.prompt : '');
|
||||||
|
$('#extension_use_floating_chara').prop('checked', charaNote ? charaNote.useChara : false);
|
||||||
|
}
|
||||||
|
|
||||||
$('#extension_floating_default').val(extension_settings.note.default);
|
$('#extension_floating_default').val(extension_settings.note.default);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +210,17 @@ async function moduleWorker() {
|
|||||||
? (lastMessageNumber % chat_metadata[metadata_keys.interval])
|
? (lastMessageNumber % chat_metadata[metadata_keys.interval])
|
||||||
: (chat_metadata[metadata_keys.interval] - lastMessageNumber);
|
: (chat_metadata[metadata_keys.interval] - lastMessageNumber);
|
||||||
const shouldAddPrompt = messagesTillInsertion == 0;
|
const shouldAddPrompt = messagesTillInsertion == 0;
|
||||||
const prompt = shouldAddPrompt ? $('#extension_floating_prompt').val() : '';
|
|
||||||
|
let prompt = shouldAddPrompt ? $('#extension_floating_prompt').val() : '';
|
||||||
|
if (shouldAddPrompt && extension_settings.note.chara) {
|
||||||
|
const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());
|
||||||
|
|
||||||
|
// Only replace with the chara note if the user checked the box
|
||||||
|
if (charaNote && charaNote.useChara) {
|
||||||
|
prompt = charaNote.prompt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
context.setExtensionPrompt(MODULE_NAME, prompt, chat_metadata[metadata_keys.position], chat_metadata[metadata_keys.depth]);
|
context.setExtensionPrompt(MODULE_NAME, prompt, chat_metadata[metadata_keys.position], chat_metadata[metadata_keys.depth]);
|
||||||
$('#extension_floating_counter').text(shouldAddPrompt ? '0' : messagesTillInsertion);
|
$('#extension_floating_counter').text(shouldAddPrompt ? '0' : messagesTillInsertion);
|
||||||
}
|
}
|
||||||
@@ -184,9 +260,23 @@ function onANMenuItemClick() {
|
|||||||
|
|
||||||
function onChatChanged() {
|
function onChatChanged() {
|
||||||
const tokenCounter1 = chat_metadata[metadata_keys.prompt] ? getTokenCount(chat_metadata[metadata_keys.prompt]) : 0;
|
const tokenCounter1 = chat_metadata[metadata_keys.prompt] ? getTokenCount(chat_metadata[metadata_keys.prompt]) : 0;
|
||||||
const tokenCounter2 = extension_settings.note.default ? getTokenCount(extension_settings.note.default) : 0;
|
|
||||||
$('#extension_floating_prompt_token_counter').text(tokenCounter1);
|
$('#extension_floating_prompt_token_counter').text(tokenCounter1);
|
||||||
$('#extension_floating_default_token_counter').text(tokenCounter2);
|
|
||||||
|
let tokenCounter2;
|
||||||
|
if (extension_settings.note.chara) {
|
||||||
|
const charaNote = extension_settings.note.chara.find((e) => e.name === getCharaFilename());
|
||||||
|
|
||||||
|
if (charaNote) {
|
||||||
|
tokenCounter2 = getTokenCount(charaNote.prompt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokenCounter2) {
|
||||||
|
$('#extension_floating_chara_token_counter').text(tokenCounter2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokenCounter3 = extension_settings.note.default ? getTokenCount(extension_settings.note.default) : 0;
|
||||||
|
$('#extension_floating_default_token_counter').text(tokenCounter3);
|
||||||
}
|
}
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
@@ -235,6 +325,25 @@ function onChatChanged() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr class="sysHR">
|
<hr class="sysHR">
|
||||||
|
<div class="inline-drawer">
|
||||||
|
<div id="charaANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||||
|
<b>Character Author's Note</b>
|
||||||
|
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||||
|
</div>
|
||||||
|
<div class="inline-drawer-content">
|
||||||
|
<small>Will be automatically added as the author's note for this character.</small>
|
||||||
|
|
||||||
|
<textarea id="extension_floating_chara" class="text_pole" rows="8" maxlength="10000"
|
||||||
|
placeholder="Example:\n[Scenario: wacky adventures; Genre: romantic comedy; Style: verbose, creative]"></textarea>
|
||||||
|
<div class="extension_token_counter">Tokens: <span id="extension_floating_chara_token_counter">0</small></div>
|
||||||
|
|
||||||
|
<label for="extension_use_floating_chara">
|
||||||
|
<input id="extension_use_floating_chara" type="checkbox" />
|
||||||
|
<span data-i18n="Use character author's note">Use character author's note</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="sysHR">
|
||||||
<div class="inline-drawer">
|
<div class="inline-drawer">
|
||||||
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
<div id="defaultANBlockToggle" class="inline-drawer-toggle inline-drawer-header">
|
||||||
<b>Default Author's Note</b>
|
<b>Default Author's Note</b>
|
||||||
@@ -263,6 +372,8 @@ function onChatChanged() {
|
|||||||
$('#extension_floating_prompt').on('input', onExtensionFloatingPromptInput);
|
$('#extension_floating_prompt').on('input', onExtensionFloatingPromptInput);
|
||||||
$('#extension_floating_interval').on('input', onExtensionFloatingIntervalInput);
|
$('#extension_floating_interval').on('input', onExtensionFloatingIntervalInput);
|
||||||
$('#extension_floating_depth').on('input', onExtensionFloatingDepthInput);
|
$('#extension_floating_depth').on('input', onExtensionFloatingDepthInput);
|
||||||
|
$('#extension_floating_chara').on('input', onExtensionFloatingCharaPromptInput);
|
||||||
|
$('#extension_use_floating_chara').on('input', onExtensionFloatingCharaCheckboxChanged);
|
||||||
$('#extension_floating_default').on('input', onExtensionFloatingDefaultInput);
|
$('#extension_floating_default').on('input', onExtensionFloatingDefaultInput);
|
||||||
$('input[name="extension_floating_position"]').on('change', onExtensionFloatingPositionInput);
|
$('input[name="extension_floating_position"]').on('change', onExtensionFloatingPositionInput);
|
||||||
$('#ANClose').on('click', function () {
|
$('#ANClose').on('click', function () {
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
import { getContext } from "./extensions.js";
|
||||||
|
|
||||||
export function onlyUnique(value, index, array) {
|
export function onlyUnique(value, index, array) {
|
||||||
return array.indexOf(value) === index;
|
return array.indexOf(value) === index;
|
||||||
}
|
}
|
||||||
@@ -420,3 +422,12 @@ export function isDataURL(str) {
|
|||||||
const regex = /^data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)*;?)?(base64)?,([a-z0-9!$&',()*+;=\-_%.~:@\/?#]+)?$/i;
|
const regex = /^data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)*;?)?(base64)?,([a-z0-9!$&',()*+;=\-_%.~:@\/?#]+)?$/i;
|
||||||
return regex.test(str);
|
return regex.test(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCharaFilename() {
|
||||||
|
const context = getContext();
|
||||||
|
const fileName = context.characters[context.characterId].avatar;
|
||||||
|
|
||||||
|
if (fileName) {
|
||||||
|
return fileName.replace(/\.[^/.]+$/, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -332,6 +332,19 @@ function appendWorldEntry(entry) {
|
|||||||
$(this).siblings("input").click();
|
$(this).siblings("input").click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const excludeRecursionInput = template.find('input[name="exclude_recursion"]');
|
||||||
|
excludeRecursionInput.data("uid", entry.uid);
|
||||||
|
excludeRecursionInput.on("input", function () {
|
||||||
|
const uid = $(this).data("uid");
|
||||||
|
const value = $(this).prop("checked");
|
||||||
|
world_info_data.entries[uid].excludeRecursion = value;
|
||||||
|
saveWorldInfo();
|
||||||
|
});
|
||||||
|
excludeRecursionInput.prop("checked", entry.excludeRecursion).trigger("input");
|
||||||
|
excludeRecursionInput.siblings(".checkbox_fancy").click(function () {
|
||||||
|
$(this).siblings("input").click();
|
||||||
|
});
|
||||||
|
|
||||||
// delete button
|
// delete button
|
||||||
const deleteButton = template.find("input.delete_entry_button");
|
const deleteButton = template.find("input.delete_entry_button");
|
||||||
deleteButton.data("uid", entry.uid);
|
deleteButton.data("uid", entry.uid);
|
||||||
@@ -366,6 +379,7 @@ function createWorldInfoEntry() {
|
|||||||
order: 100,
|
order: 100,
|
||||||
position: 0,
|
position: 0,
|
||||||
disable: false,
|
disable: false,
|
||||||
|
excludeRecursion: false
|
||||||
};
|
};
|
||||||
const newUid = getFreeWorldEntryUid();
|
const newUid = getFreeWorldEntryUid();
|
||||||
|
|
||||||
@@ -505,6 +519,7 @@ function checkWorldInfo(chat) {
|
|||||||
let worldInfoBefore = "";
|
let worldInfoBefore = "";
|
||||||
let worldInfoAfter = "";
|
let worldInfoAfter = "";
|
||||||
let needsToScan = true;
|
let needsToScan = true;
|
||||||
|
let count = 0;
|
||||||
let allActivatedEntries = new Set();
|
let allActivatedEntries = new Set();
|
||||||
|
|
||||||
const sortedEntries = Object.keys(world_info_data.entries)
|
const sortedEntries = Object.keys(world_info_data.entries)
|
||||||
@@ -512,10 +527,13 @@ function checkWorldInfo(chat) {
|
|||||||
.sort((a, b) => b.order - a.order);
|
.sort((a, b) => b.order - a.order);
|
||||||
|
|
||||||
while (needsToScan) {
|
while (needsToScan) {
|
||||||
|
// Track how many times the loop has run
|
||||||
|
count++;
|
||||||
|
|
||||||
let activatedNow = new Set();
|
let activatedNow = new Set();
|
||||||
|
|
||||||
for (let entry of sortedEntries) {
|
for (let entry of sortedEntries) {
|
||||||
if (allActivatedEntries.has(entry.uid) || entry.disable == true) {
|
if (allActivatedEntries.has(entry.uid) || entry.disable == true || (count > 1 && world_info_recursive && entry.excludeRecursion)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user