Merge branch 'staging' of http://github.com/cohee1207/SillyTavern into staging
This commit is contained in:
commit
19b3e13675
|
@ -59,7 +59,7 @@
|
|||
"trusted_workers_only": false
|
||||
},
|
||||
"power_user": {
|
||||
"tokenizer": 3,
|
||||
"tokenizer": 99,
|
||||
"token_padding": 64,
|
||||
"collapse_newlines": false,
|
||||
"pygmalion_formatting": 0,
|
||||
|
@ -147,6 +147,7 @@
|
|||
"persona_description": "",
|
||||
"persona_description_position": 0,
|
||||
"custom_stopping_strings": "",
|
||||
"custom_stopping_strings_macro": true,
|
||||
"fuzzy_search": false
|
||||
},
|
||||
"extension_settings": {
|
||||
|
|
|
@ -815,8 +815,8 @@
|
|||
<div class="fa-solid fa-clock-rotate-left "></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toggle-description justifyLeft" data-i18n="Use style tags to improve the quality of the output">
|
||||
Use style tags to improve the quality of the output
|
||||
<div class="toggle-description justifyLeft" data-i18n="Use style tags to modify the writing style of the output">
|
||||
Use style tags to modify the writing style of the output
|
||||
</div>
|
||||
<div class="wide100p">
|
||||
<textarea id="nai_preamble_textarea" class="text_pole textarea_compact" name="nai_preamble" rows="2"
|
||||
|
@ -1560,7 +1560,7 @@
|
|||
<div class="flex-container indent20p">
|
||||
<a href="https://github.com/oobabooga/text-generation-webui" target="_blank">
|
||||
oobabooga/text-generation-webui
|
||||
</a>,
|
||||
</a>
|
||||
<span data-i18n="Make sure you run it with">
|
||||
Make sure you run it with <tt>--api</tt> flag
|
||||
</span>
|
||||
|
@ -1568,7 +1568,7 @@
|
|||
<div class="flex-container indent20p">
|
||||
<a href="https://mancer.tech/" target="_blank">
|
||||
Mancer AI
|
||||
</a>,
|
||||
</a>
|
||||
<label class="checkbox_label" for="use-mancer-api-checkbox">
|
||||
<span data-i18n="Use API key (Only required for Mancer)">
|
||||
Click this box (and add your API key!):
|
||||
|
@ -1961,6 +1961,7 @@
|
|||
</a>
|
||||
</h4>
|
||||
<select id="tokenizer">
|
||||
<option value="99">Best match (recommended)</option>
|
||||
<option value="0">None / Estimated</option>
|
||||
<option value="1">GPT-3 (OpenAI)</option>
|
||||
<option value="2">GPT-3 (Alternative / Classic)</option>
|
||||
|
@ -2037,6 +2038,12 @@
|
|||
<div>
|
||||
<textarea id="custom_stopping_strings" rows="2" class="text_pole textarea_compact" placeholder="["Ford", "BMW", "Fiat"]"></textarea>
|
||||
</div>
|
||||
<label class="checkbox_label" for="custom_stopping_strings_macro">
|
||||
<input id="custom_stopping_strings_macro" type="checkbox" checked>
|
||||
<span data-i18n="Replace Macro in Custom Stopping Strings">
|
||||
Replace Macro in Custom Stopping Strings
|
||||
</span>
|
||||
</label>
|
||||
<h4>
|
||||
<span data-i18n="Pygmalion Formatting">
|
||||
Pygmalion Formatting
|
||||
|
|
|
@ -546,6 +546,25 @@ async function getClientVersion() {
|
|||
}
|
||||
}
|
||||
|
||||
function getTokenizerBestMatch() {
|
||||
if (main_api === 'novel') {
|
||||
if (nai_settings.model_novel.includes('krake') || nai_settings.model_novel.includes('euterpe')) {
|
||||
return tokenizers.CLASSIC;
|
||||
}
|
||||
if (nai_settings.model_novel.includes('clio')) {
|
||||
return tokenizers.NERD;
|
||||
}
|
||||
if (nai_settings.model_novel.includes('kayra')) {
|
||||
return tokenizers.NERD2;
|
||||
}
|
||||
}
|
||||
if (main_api === 'kobold' || main_api === 'textgenerationwebui' || main_api === 'koboldhorde') {
|
||||
return tokenizers.LLAMA;
|
||||
}
|
||||
|
||||
return power_user.NONE;
|
||||
}
|
||||
|
||||
function getTokenCount(str, padding = undefined) {
|
||||
if (typeof str !== 'string') {
|
||||
return 0;
|
||||
|
@ -563,6 +582,10 @@ function getTokenCount(str, padding = undefined) {
|
|||
}
|
||||
}
|
||||
|
||||
if (tokenizerType === tokenizers.BEST_MATCH) {
|
||||
tokenizerType = getTokenizerBestMatch();
|
||||
}
|
||||
|
||||
if (padding === undefined) {
|
||||
padding = 0;
|
||||
}
|
||||
|
@ -1727,7 +1750,11 @@ function getStoppingStrings(isImpersonate, addSpace) {
|
|||
|
||||
if (power_user.custom_stopping_strings) {
|
||||
const customStoppingStrings = getCustomStoppingStrings();
|
||||
result.push(...customStoppingStrings);
|
||||
if (power_user.custom_stopping_strings_macro) {
|
||||
result.push(...customStoppingStrings.map(x => substituteParams(x, name1, name2)));
|
||||
} else {
|
||||
result.push(...customStoppingStrings);
|
||||
}
|
||||
}
|
||||
|
||||
return addSpace ? result.map(x => `${x} `) : result;
|
||||
|
@ -2669,8 +2696,11 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
setPromtString();
|
||||
}
|
||||
|
||||
// add chat preamble
|
||||
mesSendString = addChatsPreamble(mesSendString);
|
||||
|
||||
// add a custom dingus (if defined)
|
||||
mesSendString = adjustChatsSeparator(mesSendString);
|
||||
mesSendString = addChatsSeparator(mesSendString);
|
||||
|
||||
let finalPromt =
|
||||
storyString +
|
||||
|
@ -3156,16 +3186,13 @@ function parseTokenCounts(counts, thisPromptBits) {
|
|||
});
|
||||
}
|
||||
|
||||
function adjustChatsSeparator(mesSendString) {
|
||||
if (main_api === 'novel') {
|
||||
let preamble = "\n***\n" + nai_settings.nai_preamble;
|
||||
if (!preamble.endsWith('\n')) {
|
||||
preamble += '\n';
|
||||
}
|
||||
mesSendString = preamble + mesSendString;
|
||||
}
|
||||
function addChatsPreamble(mesSendString) {
|
||||
const preamble = main_api === 'novel' ? nai_settings.preamble : "";
|
||||
return preamble + '\n' + mesSendString;
|
||||
}
|
||||
|
||||
else if (power_user.custom_chat_separator && power_user.custom_chat_separator.length) {
|
||||
function addChatsSeparator(mesSendString) {
|
||||
if (power_user.custom_chat_separator && power_user.custom_chat_separator.length) {
|
||||
mesSendString = power_user.custom_chat_separator + '\n' + mesSendString;
|
||||
}
|
||||
|
||||
|
@ -3174,6 +3201,10 @@ function adjustChatsSeparator(mesSendString) {
|
|||
mesSendString = mesSendString;
|
||||
}
|
||||
|
||||
else if (main_api === 'novel') {
|
||||
mesSendString = '\n***\n' + mesSendString;
|
||||
}
|
||||
|
||||
// add non-pygma dingus
|
||||
else if (!is_pygmalion) {
|
||||
mesSendString = '\nThen the roleplay chat between ' + name1 + ' and ' + name2 + ' begins.\n' + mesSendString;
|
||||
|
@ -7005,13 +7036,13 @@ function doCloseChat() {
|
|||
*
|
||||
* @param {string} popup_type - The type of popup currently active.
|
||||
* @param {string} this_chid - The character ID to be deleted.
|
||||
* @param {boolean} delete_chats - Whether to delete chats or not.
|
||||
*/
|
||||
export async function handleDeleteCharacter(popup_type, this_chid) {
|
||||
export async function handleDeleteCharacter(popup_type, this_chid, delete_chats) {
|
||||
if (popup_type !== "del_ch") {
|
||||
return;
|
||||
}
|
||||
|
||||
const delete_chats = !!$("#del_char_checkbox").prop("checked");
|
||||
const avatar = characters[this_chid].avatar;
|
||||
const name = characters[this_chid].name;
|
||||
|
||||
|
@ -7449,7 +7480,8 @@ $(document).ready(function () {
|
|||
}, 200);
|
||||
}
|
||||
if (popup_type == "del_ch") {
|
||||
handleDeleteCharacter(popup_type, this_chid, characters);
|
||||
const deleteChats = !!$("#del_char_checkbox").prop("checked");
|
||||
await handleDeleteCharacter(popup_type, this_chid, deleteChats);
|
||||
}
|
||||
if (popup_type == "alternate_greeting" && menu_type !== "create") {
|
||||
createOrEditCharacter();
|
||||
|
@ -7725,7 +7757,7 @@ $(document).ready(function () {
|
|||
const enabled = $("#use-mancer-api-checkbox").prop("checked");
|
||||
$("#mancer-api-ui").toggle(enabled);
|
||||
api_use_mancer_webui = enabled;
|
||||
saveSettingsDebounced();
|
||||
saveSettingsDebounced();
|
||||
getStatus();
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { characters, getCharacters, saveSettingsDebounced, handleDeleteCharacter } from "../../../script.js";
|
||||
import { characters, getCharacters, handleDeleteCharacter, callPopup } from "../../../script.js";
|
||||
|
||||
let is_bulk_edit = false;
|
||||
|
||||
|
@ -27,7 +27,7 @@ function onEditButtonClick() {
|
|||
* @param {string} this_chid - The chid of the character to delete.
|
||||
*/
|
||||
async function deleteCharacter(this_chid) {
|
||||
await handleDeleteCharacter("del_ch", this_chid);
|
||||
await handleDeleteCharacter("del_ch", this_chid, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,6 +45,13 @@ async function onDeleteButtonClick() {
|
|||
toDelete.push(avatar);
|
||||
});
|
||||
|
||||
const confirm = await callPopup('<h3>Are you sure you want to delete these characters?</h3>You would need to delete the chat files manually.<br>', 'confirm');
|
||||
|
||||
if (!confirm) {
|
||||
console.log('User cancelled delete');
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete the characters
|
||||
for (const avatar of toDelete) {
|
||||
console.log(`Deleting character with avatar ${avatar}`);
|
||||
|
@ -78,7 +85,7 @@ function addButtons() {
|
|||
* Enables bulk selection by adding a checkbox next to each character.
|
||||
*/
|
||||
function enableBulkSelect() {
|
||||
$(".character_select").each((i, el) => {
|
||||
$("#rm_print_characters_block .character_select").each((i, el) => {
|
||||
const character = $(el).text();
|
||||
const checkbox = $("<input type='checkbox' class='bulk_select_checkbox'>");
|
||||
checkbox.on("change", () => {
|
||||
|
@ -86,6 +93,7 @@ function enableBulkSelect() {
|
|||
});
|
||||
$(el).prepend(checkbox);
|
||||
});
|
||||
$("#rm_print_characters_block").addClass("bulk_select");
|
||||
// We also need to disable the default click event for the character_select divs
|
||||
$(document).on("click", ".bulk_select_checkbox", function (event) {
|
||||
event.stopImmediatePropagation();
|
||||
|
@ -97,6 +105,7 @@ function enableBulkSelect() {
|
|||
*/
|
||||
function disableBulkSelect() {
|
||||
$(".bulk_select_checkbox").remove();
|
||||
$("#rm_print_characters_block").removeClass("bulk_select");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
.bulk_select_checkbox {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
#rm_print_characters_block .wide100pLess70px {
|
||||
width: calc(100% - 85px);
|
||||
}
|
|
@ -45,8 +45,6 @@ let lastCharacter = undefined;
|
|||
let lastMessage = null;
|
||||
let spriteCache = {};
|
||||
let inApiCall = false;
|
||||
let previousSrc = null;
|
||||
|
||||
|
||||
function isVisualNovelMode() {
|
||||
return Boolean(!isMobile() && power_user.waifuMode && getContext().groupId);
|
||||
|
@ -395,6 +393,21 @@ function onExpressionsShowDefaultInput() {
|
|||
}
|
||||
}
|
||||
|
||||
async function unloadLiveChar() {
|
||||
try {
|
||||
const url = new URL(getApiUrl());
|
||||
url.pathname = '/api/live2d/unload';
|
||||
const loadResponse = await doExtrasFetch(url);
|
||||
if (!loadResponse.ok) {
|
||||
throw new Error(loadResponse.statusText);
|
||||
}
|
||||
const loadResponseText = await loadResponse.text();
|
||||
//console.log(`Response: ${loadResponseText}`);
|
||||
} catch (error) {
|
||||
//console.error(`Error unloading - ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadLiveChar() {
|
||||
if (!modules.includes('live2d')) {
|
||||
console.debug('live2d module is disabled');
|
||||
|
@ -456,7 +469,6 @@ function handleImageChange() {
|
|||
}
|
||||
|
||||
if (extension_settings.expressions.live2d) {
|
||||
previousSrc = imgElement.src;
|
||||
// Method get IP of endpoint
|
||||
const live2dResultFeedSrc = `${getApiUrl()}/api/live2d/result_feed`;
|
||||
$('#expression-holder').css({ display: '' });
|
||||
|
@ -496,7 +508,6 @@ async function moduleWorker() {
|
|||
if (context.groupId !== lastCharacter && context.characterId !== lastCharacter) {
|
||||
removeExpression();
|
||||
spriteCache = {};
|
||||
previousSrc = null;
|
||||
|
||||
//clear expression
|
||||
let imgElement = document.getElementById('expression-image');
|
||||
|
@ -611,12 +622,62 @@ async function moduleWorker() {
|
|||
}
|
||||
}
|
||||
|
||||
async function live2dcheck() {
|
||||
const context = getContext();
|
||||
let spriteFolderName = context.name2;
|
||||
const message = getLastCharacterMessage();
|
||||
const avatarFileName = getSpriteFolderName(message);
|
||||
const expressionOverride = extension_settings.expressionOverrides.find((e) =>
|
||||
e.name == avatarFileName
|
||||
);
|
||||
|
||||
if (expressionOverride && expressionOverride.path) {
|
||||
spriteFolderName = expressionOverride.path;
|
||||
}
|
||||
|
||||
try {
|
||||
await validateImages(spriteFolderName);
|
||||
|
||||
let live2dObj = spriteCache[spriteFolderName].find(obj => obj.label === 'live2d');
|
||||
let live2dPath_f = live2dObj ? live2dObj.path : null;
|
||||
|
||||
if(live2dPath_f != null){
|
||||
//console.log("live2dPath_f " + live2dPath_f);
|
||||
return true;
|
||||
} else {
|
||||
//console.log("live2dPath_f is null");
|
||||
unloadLiveChar();
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
function setLive2dState(switch_var){
|
||||
extension_settings.expressions.live2d = switch_var; // Store setting
|
||||
saveSettingsDebounced();
|
||||
|
||||
if (extension_settings.expressions.live2d) { loadLiveChar(); } // load char as needed
|
||||
handleImageChange(switch_var); // Change image as needed
|
||||
live2dcheck().then(result => {
|
||||
if (result) {
|
||||
//console.log("Live2d exists!");
|
||||
|
||||
if (extension_settings.expressions.live2d) {
|
||||
loadLiveChar();
|
||||
} else {
|
||||
unloadLiveChar();
|
||||
}
|
||||
handleImageChange(switch_var); // Change image as needed
|
||||
|
||||
|
||||
} else {
|
||||
//console.log("Live2d does not exist.");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function getSpriteFolderName(message) {
|
||||
|
@ -917,13 +978,25 @@ async function setExpression(character, expression, force) {
|
|||
document.getElementById("expression-holder").style.display = '';
|
||||
|
||||
} else {
|
||||
// Find the <img> element with id="expression-image" and class="expression"
|
||||
const imgElement = document.querySelector('img#expression-image.expression');
|
||||
//console.log("searching");
|
||||
if (imgElement) {
|
||||
console.log("setting value");
|
||||
imgElement.src = getApiUrl() + '/api/live2d/result_feed';
|
||||
|
||||
|
||||
live2dcheck().then(result => {
|
||||
if (result) {
|
||||
// Find the <img> element with id="expression-image" and class="expression"
|
||||
const imgElement = document.querySelector('img#expression-image.expression');
|
||||
//console.log("searching");
|
||||
if (imgElement) {
|
||||
//console.log("setting value");
|
||||
imgElement.src = getApiUrl() + '/api/live2d/result_feed';
|
||||
}
|
||||
|
||||
} else {
|
||||
//console.log("The fetch failed!");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ function loadNovelSettings(settings) {
|
|||
$(`#model_novel_select option[value=${nai_settings.model_novel}]`).attr("selected", true);
|
||||
$('#model_novel_select').val(nai_settings.model_novel);
|
||||
|
||||
if (settings.nai_preamble !== undefined) nai_settings.nai_preamble = settings.nai_preamble;
|
||||
if (settings.nai_preamble !== undefined) nai_settings.preamble = settings.nai_preamble;
|
||||
nai_settings.preset_settings_novel = settings.preset_settings_novel;
|
||||
nai_settings.temperature = settings.temperature;
|
||||
nai_settings.repetition_penalty = settings.repetition_penalty;
|
||||
|
@ -347,13 +347,13 @@ export async function generateNovelWithStreaming(generate_data, signal) {
|
|||
}
|
||||
|
||||
$("#nai_preamble_textarea").on('input', function () {
|
||||
nai_settings.nai_preamble = $('#nai_preamble_textarea').val();
|
||||
nai_settings.preamble = $('#nai_preamble_textarea').val();
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$("#nai_preamble_restore").on('click', function () {
|
||||
nai_settings.nai_preamble = default_preamble;
|
||||
$('#nai_preamble_textarea').val(nai_settings.nai_preamble);
|
||||
nai_settings.preamble = default_preamble;
|
||||
$('#nai_preamble_textarea').val(nai_settings.preamble);
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ const tokenizers = {
|
|||
NERD: 4,
|
||||
NERD2: 5,
|
||||
API: 6,
|
||||
BEST_MATCH: 99,
|
||||
}
|
||||
|
||||
const send_on_enter_options = {
|
||||
|
@ -87,7 +88,7 @@ export const persona_description_positions = {
|
|||
}
|
||||
|
||||
let power_user = {
|
||||
tokenizer: tokenizers.CLASSIC,
|
||||
tokenizer: tokenizers.BEST_MATCH,
|
||||
token_padding: 64,
|
||||
collapse_newlines: false,
|
||||
pygmalion_formatting: pygmalion_options.AUTO,
|
||||
|
@ -187,6 +188,7 @@ let power_user = {
|
|||
persona_show_notifications: true,
|
||||
|
||||
custom_stopping_strings: '',
|
||||
custom_stopping_strings_macro: true,
|
||||
fuzzy_search: false,
|
||||
};
|
||||
|
||||
|
@ -678,6 +680,7 @@ function loadPowerUserSettings(settings, data) {
|
|||
$('#auto_swipe_blacklist').val(power_user.auto_swipe_blacklist.join(", "));
|
||||
$('#auto_swipe_blacklist_threshold').val(power_user.auto_swipe_blacklist_threshold);
|
||||
$('#custom_stopping_strings').val(power_user.custom_stopping_strings);
|
||||
$("#custom_stopping_strings_macro").prop("checked", power_user.custom_stopping_strings_macro);
|
||||
$('#fuzzy_search_checkbox').prop("checked", power_user.fuzzy_search);
|
||||
$('#persona_show_notifications').prop("checked", power_user.persona_show_notifications);
|
||||
|
||||
|
@ -1995,6 +1998,11 @@ $(document).ready(() => {
|
|||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$("#custom_stopping_strings_macro").change(function () {
|
||||
power_user.custom_stopping_strings_macro = !!$(this).prop("checked");
|
||||
saveSettingsDebounced();
|
||||
});
|
||||
|
||||
$('#fuzzy_search_checkbox').on('input', function () {
|
||||
power_user.fuzzy_search = !!$(this).prop('checked');
|
||||
saveSettingsDebounced();
|
||||
|
|
|
@ -1169,7 +1169,7 @@ app.post("/deletecharacter", jsonParser, async function (request, response) {
|
|||
return response.sendStatus(403);
|
||||
}
|
||||
|
||||
if (request.body.delete_chats == 'true') {
|
||||
if (request.body.delete_chats == true) {
|
||||
try {
|
||||
await fs.promises.rm(path.join(chatsPath, sanitize(dir_name)), { recursive: true, force: true })
|
||||
} catch (err) {
|
||||
|
@ -3475,7 +3475,7 @@ app.post("/tokenize_via_api", jsonParser, async function (request, response) {
|
|||
body: JSON.stringify({ "prompt": text }),
|
||||
headers: { "Content-Type": "application/json" }
|
||||
};
|
||||
|
||||
|
||||
if (main_api == 'textgenerationwebui' && request.body.use_mancer) {
|
||||
args.headers = Object.assign(args.headers, get_mancer_headers());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue