Merge branch 'dev' of https://github.com/SillyTavern/SillyTavern into smartcontext-improvements

This commit is contained in:
50h100a
2023-07-07 13:03:00 -04:00
12 changed files with 246 additions and 114 deletions

View File

@@ -152,7 +152,7 @@ async function visualNovelSetCharacterSprites(container, name, expression) {
const path = currentSpritePath || defaultSpritePath || '';
const img = expressionImage.find('img');
setImage(img, path);
await setImage(img, path);
}
expressionImage.toggleClass('hidden', noSprites);
} else {
@@ -163,7 +163,7 @@ async function visualNovelSetCharacterSprites(container, name, expression) {
$('#visual-novel-wrapper').append(template);
dragElement($(template[0]));
template.toggleClass('hidden', noSprites);
setImage(template.find('img'), defaultSpritePath || '');
await setImage(template.find('img'), defaultSpritePath || '');
const fadeInPromise = new Promise(resolve => {
template.fadeIn(250, () => resolve());
});
@@ -284,7 +284,9 @@ async function setLastMessageSprite(img, avatar, labels) {
}
}
function setImage(img, path) {
async function setImage(img, path) {
// Cohee: If something goes wrong, uncomment this to return to the old behavior
/*
img.attr('src', path);
img.removeClass('default');
img.off('error');
@@ -293,6 +295,66 @@ function setImage(img, path) {
$(this).off('error');
$(this).attr('src', '');
});
*/
return new Promise(resolve => {
const prevExpressionSrc = img.attr('src');
const expressionClone = img.clone();
const originalId = img.attr('id');
//only swap expressions when necessary
if (prevExpressionSrc !== path && !img.hasClass('expression-animating')) {
//clone expression
expressionClone.addClass('expression-clone')
//make invisible and remove id to prevent double ids
//must be made invisible to start because they share the same Z-index
expressionClone.attr('id', '').css({ opacity: 0 });
//add new sprite path to clone src
expressionClone.attr('src', path);
//add invisible clone to html
expressionClone.appendTo(img.parent());
const duration = 200;
//add animation flags to both images
//to prevent multiple expression changes happening simultaneously
img.addClass('expression-animating')
//position absolute prevent the original from jumping around during transition
img.css('position', 'absolute')
expressionClone.addClass('expression-animating')
//fade the clone in
expressionClone.css({
opacity: 0
}).animate({
opacity: 1
}, duration)
//when finshed fading in clone, fade out the original
.promise().done(function () {
img.animate({
opacity: 0
}, duration);
//remove old expression
img.remove();
//replace ID so it becomes the new 'original' expression for next change
expressionClone.attr('id', originalId);
expressionClone.removeClass('expression-animating');
resolve();
});
expressionClone.removeClass('expression-clone');
expressionClone.removeClass('default');
expressionClone.off('error');
expressionClone.on('error', function () {
console.debug('Expression image error', sprite.path);
$(this).attr('src', '');
$(this).off('error');
resolve();
});
} else {
resolve();
}
});
}
function onExpressionsShowDefaultInput() {
@@ -620,6 +682,8 @@ async function setExpression(character, expression, force) {
console.debug('entered setExpressions');
await validateImages(character);
const img = $('img.expression');
const prevExpressionSrc = img.attr('src');
const expressionClone = img.clone()
const sprite = (spriteCache[character] && spriteCache[character].find(x => x.label === expression));
console.debug('checking for expression images to show..');
@@ -638,26 +702,67 @@ async function setExpression(character, expression, force) {
}
if (groupMember.name == character) {
setImage($(`.expression-holder[data-avatar="${member}"] img`), sprite.path);
await setImage($(`.expression-holder[data-avatar="${member}"] img`), sprite.path);
return;
}
}
}
//only swap expressions when necessary
if (prevExpressionSrc !== sprite.path
&& !img.hasClass('expression-animating')) {
//clone expression
expressionClone.addClass('expression-clone')
//make invisible and remove id to prevent double ids
//must be made invisible to start because they share the same Z-index
expressionClone.attr('id', '').css({ opacity: 0 });
//add new sprite path to clone src
expressionClone.attr('src', sprite.path);
//add invisible clone to html
expressionClone.appendTo($("#expression-holder"))
img.attr('src', sprite.path);
img.removeClass('default');
img.off('error');
img.on('error', function () {
console.debug('Expression image error', sprite.path);
$(this).attr('src', '');
$(this).off('error');
if (force && extension_settings.expressions.showDefault) {
const duration = 200;
//add animation flags to both images
//to prevent multiple expression changes happening simultaneously
img.addClass('expression-animating')
//position absolute prevent the original from jumping around during transition
img.css('position', 'absolute')
expressionClone.addClass('expression-animating')
//fade the clone in
expressionClone.css({
opacity: 0
}).animate({
opacity: 1
}, duration)
//when finshed fading in clone, fade out the original
.promise().done(function () {
img.animate({
opacity: 0
}, duration);
//remove old expression
img.remove();
//replace ID so it becomes the new 'original' expression for next change
expressionClone.attr('id', 'expression-image')
expressionClone.removeClass('expression-animating')
});
expressionClone.removeClass('expression-clone');
expressionClone.removeClass('default');
expressionClone.off('error');
expressionClone.on('error', function () {
console.debug('Expression image error', sprite.path);
$(this).attr('src', '');
$(this).off('error');
if (force && extension_settings.expressions.showDefault) {
setDefault();
}
});
} else {
if (extension_settings.expressions.showDefault) {
setDefault();
}
});
} else {
if (extension_settings.expressions.showDefault) {
setDefault();
}
}
@@ -665,8 +770,8 @@ async function setExpression(character, expression, force) {
console.debug('setting default');
const defImgUrl = `/img/default-expressions/${expression}.png`;
//console.log(defImgUrl);
img.attr('src', defImgUrl);
img.addClass('default');
expressionClone.attr('src', defImgUrl);
expressionClone.addClass('default');
}
document.getElementById("expression-holder").style.display = '';
}

View File

@@ -20,6 +20,9 @@
#visual-novel-wrapper .expression-holder {
width: max-content;
display: flex;
left: unset;
right: unset;
}
#visual-novel-wrapper .hidden {
@@ -31,21 +34,6 @@
object-fit: cover;
}*/
/* .expression-holder {
min-width: 100px;
min-height: 100px;
max-height: 90vh;
max-width: 90vh;
width: calc((100vw - var(--sheldWidth)) /2);
position: absolute;
padding: 0;
filter: drop-shadow(2px 2px 2px #51515199);
z-index: 29;
overflow: hidden;
display: none;
bottom: 0;
} */
.expression-holder {
min-width: 100px;
min-height: 100px;
@@ -55,6 +43,7 @@
position: absolute;
bottom: 0;
padding: 0;
left: 0;
filter: drop-shadow(2px 2px 2px #51515199);
z-index: 2;
overflow: hidden;
@@ -62,8 +51,13 @@
}
img.expression {
min-width: 100px;
min-height: 100px;
max-height: 90vh;
max-width: 90vh;
width: 100%;
height: 100%;
bottom: 0;
padding: 0;
vertical-align: bottom;
object-fit: contain;
}
@@ -79,6 +73,10 @@ img.expression.default {
margin-top: 50px;
}
.expression-clone {
position: absolute;
}
.debug-image {
display: none;
visibility: collapse;

View File

@@ -133,20 +133,7 @@ async function loadSettings() {
function onStrategyChange() {
console.debug('changing chromadb strat');
extension_settings.chromadb.strategy = $('#chromadb_strategy').val();
$('#chromadb_custom_depth').hide();
$('label[for="chromadb_custom_depth"]').hide();
$('#chromadb_custom_msg').hide();
$('label[for="chromadb_custom_msg"]').hide();
$('#chromadb_hhaa_wrapperfmt').hide();
$('label[for="chromadb_hhaa_wrapperfmt"]').hide();
$('#chromadb_hhaa_memoryfmt').hide();
$('label[for="chromadb_hhaa_memoryfmt"]').hide();
$('#chromadb_hhaa_token_limit').hide();
$('label[for="chromadb_hhaa_token_limit"]').hide();
if(extension_settings.chromadb.strategy === "custom"){
if (extension_settings.chromadb.strategy === "custom") {
$('#chromadb_custom_depth').show();
$('label[for="chromadb_custom_depth"]').show();
$('#chromadb_custom_msg').show();
@@ -226,6 +213,16 @@ function onFileSplitLengthInput() {
saveSettingsDebounced();
}
function onChunkNLInput() {
let shouldSplit = $('#onChunkNLInput').is(':checked');
if (shouldSplit) {
extension_settings.chromadb.file_split_type = "newline";
} else {
extension_settings.chromadb.file_split_type = "length";
}
saveSettingsDebounced();
}
function checkChatId(chat_id) {
if (!chat_id || chat_id.trim() === '') {
toastr.error('Please select a character and try again.');
@@ -450,7 +447,7 @@ async function queryMultiMessages(chat_id, query) {
const context = getContext();
const response = await fetch("/getallchatsofcharacter", {
method: 'POST',
body: JSON.stringify({ avatar_url: context.characters[context.characterId].avatar}),
body: JSON.stringify({ avatar_url: context.characters[context.characterId].avatar }),
headers: getRequestHeaders(),
});
if (!response.ok) {
@@ -492,8 +489,14 @@ async function onSelectInjectFile(e) {
try {
toastr.info('This may take some time, depending on the file size', 'Processing...');
const text = await getFileText(file);
const split = splitRecursive(text, extension_settings.chromadb.file_split_length).filter(onlyUnique);
extension_settings.chromadb.file_split_type = "newline";
//allow splitting on newlines or splitrecursively
let split = [];
if (extension_settings.chromadb.file_split_type == "newline") {
split = text.split(/\r?\n/).filter(onlyUnique);
} else {
split = splitRecursive(text, extension_settings.chromadb.file_split_length).filter(onlyUnique);
}
const baseDate = Date.now();
const messages = split.map((m, i) => ({
@@ -590,6 +593,9 @@ window.chromadb_interceptGeneration = async (chat, maxContext) => {
if (!currentChatId)
return;
//log the current settings
console.debug("CHROMADB: Current settings: %o", extension_settings.chromadb);
const selectedStrategy = extension_settings.chromadb.strategy;
const recallStrategy = extension_settings.chromadb.recall_strategy;
let recallMsg = extension_settings.chromadb.recall_msg || defaultSettings.chroma_default_msg;
@@ -599,6 +605,10 @@ window.chromadb_interceptGeneration = async (chat, maxContext) => {
const messagesToStore = chat.slice(0, -extension_settings.chromadb.keep_context);
if (messagesToStore.length > 0 && !extension_settings.chromadb.freeze) {
//log the messages to store
console.debug("CHROMADB: Messages to store: %o", messagesToStore);
//log the messages to store length vs keep context
console.debug("CHROMADB: Messages to store length vs keep context: %o vs %o", messagesToStore.length, extension_settings.chromadb.keep_context);
await addMessages(currentChatId, messagesToStore);
}
@@ -618,18 +628,18 @@ window.chromadb_interceptGeneration = async (chat, maxContext) => {
}
console.log("ChromDB Query text:", queryBlob);
if (recallStrategy === 'multichat'){
if (recallStrategy === 'multichat') {
console.log("Utilizing multichat")
queriedMessages = await queryMultiMessages(currentChatId, queryBlob);
}
else{
else {
queriedMessages = await queryMessages(currentChatId, queryBlob);
}
if(chromaSortStrategy === "date"){
if (chromaSortStrategy === "date") {
queriedMessages.sort((a, b) => a.date - b.date);
}
else{
else {
queriedMessages.sort((a, b) => b.distance - a.distance);
}
console.log(queriedMessages);
@@ -727,10 +737,10 @@ window.chromadb_interceptGeneration = async (chat, maxContext) => {
let chatset = new Set(chat.map(obj => obj.mes));
newChat = newChat.filter(obj => !chatset.has(obj.mes));
if(chromaDepth === -1){
if(chromaDepth === -1) {
chat.splice(chat.length, 0, ...newChat);
}
else{
else {
chat.splice(chromaDepth, 0, ...newChat);
}
}
@@ -741,7 +751,6 @@ window.chromadb_interceptGeneration = async (chat, maxContext) => {
chat.splice(0, messagesToStore.length, ...newChat);
}
console.log('ChromaDB chat after injection', chat);
}
}
@@ -837,6 +846,10 @@ jQuery(async () => {
<input type="checkbox" id="chromadb_auto_adjust" />
<span>Use % strategy</span>
</label>
<label class="checkbox_label" for="chromadb_chunk_nl" title="Chunk injected documents on newline instead of at set character size." >
<input type="checkbox" id="chromadb_chunk_nl" />
<span>Chunk on Newlines</span>
</label>
<label class="checkbox_label for="chromadb_query_last_only" title="ChromaDB queries only use the most recent message. (Instead of using all messages still in the context.)">
<input type="checkbox" id="chromadb_query_last_only" />
<span>Query last message only</span>
@@ -887,6 +900,7 @@ jQuery(async () => {
$('#chromadb_purge').on('click', onPurgeClick);
$('#chromadb_export').on('click', onExportClick);
$('#chromadb_freeze').on('input', onFreezeInput);
$('#chromadb_chunk_nl').on('input', onChunkNLInput);
$('#chromadb_auto_adjust').on('input', onAutoAdjustInput);
$('#chromadb_query_last_only').on('input', onFullLogQuery);
$('#chromadb_keep_context_proportion').on('input', onKeepContextProportionInput);

View File

@@ -39,14 +39,14 @@ function regexFromString(input) {
// Parent function to fetch a regexed version of a raw string
function getRegexedString(rawString, placement, { characterOverride } = {}) {
let finalString = rawString;
if (extension_settings.disabledExtensions.includes("regex") || !rawString || placement === undefined) {
return;
return finalString;
}
let finalString;
extension_settings.regex.forEach((script) => {
if (script.placement.includes(placement)) {
finalString = runRegexScript(script, rawString, { characterOverride });
finalString = runRegexScript(script, finalString, { characterOverride });
}
});
@@ -55,17 +55,17 @@ function getRegexedString(rawString, placement, { characterOverride } = {}) {
// Runs the provided regex script on the given string
function runRegexScript(regexScript, rawString, { characterOverride } = {}) {
let newString = rawString;
if (!regexScript || !!(regexScript.disabled) || !regexScript?.findRegex || !rawString) {
return;
return newString;
}
let match;
let newString;
const findRegex = regexFromString(regexScript.substituteRegex ? substituteParams(regexScript.findRegex) : regexScript.findRegex);
// The user skill issued. Return with nothing.
if (!findRegex) {
return;
return newString;
}
while ((match = findRegex.exec(rawString)) !== null) {