Merge branch 'staging' of https://github.com/Tony-sama/SillyTavern into staging
This commit is contained in:
commit
362df6b144
|
@ -608,6 +608,10 @@
|
||||||
<input type="number" id="openai_max_tokens" name="openai_max_tokens" class="text_pole" min="50" max="1000">
|
<input type="number" id="openai_max_tokens" name="openai_max_tokens" class="text_pole" min="50" max="1000">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div data-source="openrouter">
|
||||||
|
Max prompt cost: <span id="openrouter_max_prompt_cost">Unknown</span>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
<div class="range-block" data-source="openai,claude,windowai,openrouter">
|
<div class="range-block" data-source="openai,claude,windowai,openrouter">
|
||||||
<div class="range-block-title" data-i18n="Temperature">
|
<div class="range-block-title" data-i18n="Temperature">
|
||||||
Temperature
|
Temperature
|
||||||
|
@ -1774,9 +1778,6 @@
|
||||||
<select id="model_openrouter_select">
|
<select id="model_openrouter_select">
|
||||||
<option data-i18n="Connect to the API">-- Connect to the API --</option>
|
<option data-i18n="Connect to the API">-- Connect to the API --</option>
|
||||||
</select>
|
</select>
|
||||||
<small>
|
|
||||||
Max prompt cost: <span id="openrouter_max_prompt_cost">Unknown</span>
|
|
||||||
</small>
|
|
||||||
</div>
|
</div>
|
||||||
<h4 data-i18n="OpenRouter API Key">OpenRouter API Key</h4>
|
<h4 data-i18n="OpenRouter API Key">OpenRouter API Key</h4>
|
||||||
<div>
|
<div>
|
||||||
|
@ -2140,7 +2141,7 @@
|
||||||
<div class="justifyContentSpaceAround wi-settings flex-container gap10px alignitemscenter">
|
<div class="justifyContentSpaceAround wi-settings flex-container gap10px alignitemscenter">
|
||||||
<div id="WIMultiSelector" class="flex2 flex alignSelfStart range-block">
|
<div id="WIMultiSelector" class="flex2 flex alignSelfStart range-block">
|
||||||
<div class="range-block-title justifyLeft">
|
<div class="range-block-title justifyLeft">
|
||||||
<span data-i18n="Active World(s)"><small>Active World(s)</small></span>
|
<span data-i18n="Active World(s) for all chats"><small>Active World(s) for all chats</small></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="range-block-range">
|
<div class="range-block-range">
|
||||||
<select id="world_info" multiple>
|
<select id="world_info" multiple>
|
||||||
|
@ -2185,7 +2186,7 @@
|
||||||
|
|
||||||
<div class="flex1 gap5px range-block">
|
<div class="flex1 gap5px range-block">
|
||||||
<div class="wide10pMinFit">
|
<div class="wide10pMinFit">
|
||||||
<small data-i18n="Token Budget">Context %</small>
|
<small data-i18n="Context %">Context %</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="range-block-range-and-counter ">
|
<div class="range-block-range-and-counter ">
|
||||||
<div class="range-block-range paddingLeftRight5">
|
<div class="range-block-range paddingLeftRight5">
|
||||||
|
@ -2198,6 +2199,25 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex1 gap5px range-block">
|
||||||
|
<div class="wide10pMinFit">
|
||||||
|
<small data-i18n="Budget Cap">Budget Cap</small>
|
||||||
|
</div>
|
||||||
|
<div class="range-block-range-and-counter ">
|
||||||
|
<div class="range-block-range paddingLeftRight5">
|
||||||
|
<input type="range" id="world_info_budget_cap" name="volume" min="0" max="8192" step="256">
|
||||||
|
</div>
|
||||||
|
<div class="range-block-counter margin0">
|
||||||
|
<div contenteditable="true" data-for="world_info_budget_cap" id="world_info_budget_cap_counter">
|
||||||
|
0
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="budget_cap_note">
|
||||||
|
<small data-i18n="(0 = disabled)">(0 = disabled)</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -21,17 +21,11 @@ import {
|
||||||
} from "./scripts/textgen-settings.js";
|
} from "./scripts/textgen-settings.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
world_info_budget,
|
|
||||||
world_info_depth,
|
|
||||||
world_info,
|
world_info,
|
||||||
getWorldInfoPrompt,
|
getWorldInfoPrompt,
|
||||||
|
getWorldInfoSettings,
|
||||||
setWorldInfoSettings,
|
setWorldInfoSettings,
|
||||||
world_info_recursive,
|
|
||||||
world_info_overflow_alert,
|
|
||||||
world_info_case_sensitive,
|
|
||||||
world_info_match_whole_words,
|
|
||||||
world_names,
|
world_names,
|
||||||
world_info_character_strategy,
|
|
||||||
importEmbeddedWorldInfo,
|
importEmbeddedWorldInfo,
|
||||||
checkEmbeddedWorld,
|
checkEmbeddedWorld,
|
||||||
setWorldInfoButtonClass,
|
setWorldInfoButtonClass,
|
||||||
|
@ -102,10 +96,12 @@ import {
|
||||||
import {
|
import {
|
||||||
generateNovelWithStreaming,
|
generateNovelWithStreaming,
|
||||||
getNovelGenerationData,
|
getNovelGenerationData,
|
||||||
|
getNovelMaxContextTokens,
|
||||||
getNovelTier,
|
getNovelTier,
|
||||||
loadNovelPreset,
|
loadNovelPreset,
|
||||||
loadNovelSettings,
|
loadNovelSettings,
|
||||||
nai_settings,
|
nai_settings,
|
||||||
|
setNovelData,
|
||||||
} from "./scripts/nai-settings.js";
|
} from "./scripts/nai-settings.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -797,7 +793,6 @@ let extension_prompts = {};
|
||||||
|
|
||||||
var main_api;// = "kobold";
|
var main_api;// = "kobold";
|
||||||
//novel settings
|
//novel settings
|
||||||
let novel_tier;
|
|
||||||
export let novelai_settings;
|
export let novelai_settings;
|
||||||
export let novelai_setting_names;
|
export let novelai_setting_names;
|
||||||
let abortController;
|
let abortController;
|
||||||
|
@ -3176,14 +3171,22 @@ function getMaxContextSize() {
|
||||||
this_max_context = Number(max_context);
|
this_max_context = Number(max_context);
|
||||||
if (nai_settings.model_novel == 'krake-v2' || nai_settings.model_novel == 'euterpe-v2') {
|
if (nai_settings.model_novel == 'krake-v2' || nai_settings.model_novel == 'euterpe-v2') {
|
||||||
// Krake and Euterpe have a max context of 2048
|
// Krake and Euterpe have a max context of 2048
|
||||||
// Should be used with nerdstash tokenizer for best results
|
// Should be used with classic gpt tokenizer for best results
|
||||||
this_max_context = Math.min(max_context, 2048);
|
this_max_context = Math.min(max_context, 2048);
|
||||||
}
|
}
|
||||||
if (nai_settings.model_novel == 'clio-v1' || nai_settings.model_novel == 'kayra-v1') {
|
if (nai_settings.model_novel == 'clio-v1' || nai_settings.model_novel == 'kayra-v1') {
|
||||||
// Clio and Kayra has a max context of 8192
|
// Clio and Kayra have a max context of 8192
|
||||||
// Should be used with nerdstash / nerdstash_v2 tokenizer for best results
|
// Should be used with nerdstash / nerdstash_v2 tokenizer for best results
|
||||||
this_max_context = Math.min(max_context, 8192);
|
this_max_context = Math.min(max_context, 8192);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const subscriptionLimit = getNovelMaxContextTokens();
|
||||||
|
if (typeof subscriptionLimit === "number" && this_max_context > subscriptionLimit) {
|
||||||
|
this_max_context = subscriptionLimit;
|
||||||
|
console.log(`NovelAI subscription limit reached. Max context size is now ${this_max_context}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this_max_context = this_max_context - amount_gen;
|
||||||
}
|
}
|
||||||
if (main_api == 'openai') {
|
if (main_api == 'openai') {
|
||||||
this_max_context = oai_settings.openai_max_context;
|
this_max_context = oai_settings.openai_max_context;
|
||||||
|
@ -5154,7 +5157,7 @@ async function getSettings(type) {
|
||||||
api_server = settings.api_server;
|
api_server = settings.api_server;
|
||||||
$("#api_url_text").val(api_server);
|
$("#api_url_text").val(api_server);
|
||||||
|
|
||||||
setWorldInfoSettings(settings, data);
|
setWorldInfoSettings(settings.world_info_settings ?? settings, data);
|
||||||
|
|
||||||
api_server_textgenerationwebui = settings.api_server_textgenerationwebui;
|
api_server_textgenerationwebui = settings.api_server_textgenerationwebui;
|
||||||
$("#textgenerationwebui_api_url_text").val(
|
$("#textgenerationwebui_api_url_text").val(
|
||||||
|
@ -5202,14 +5205,7 @@ async function saveSettings(type) {
|
||||||
amount_gen: amount_gen,
|
amount_gen: amount_gen,
|
||||||
max_context: max_context,
|
max_context: max_context,
|
||||||
main_api: main_api,
|
main_api: main_api,
|
||||||
world_info: world_info,
|
world_info_settings: getWorldInfoSettings(),
|
||||||
world_info_depth: world_info_depth,
|
|
||||||
world_info_budget: world_info_budget,
|
|
||||||
world_info_recursive: world_info_recursive,
|
|
||||||
world_info_overflow_alert: world_info_overflow_alert,
|
|
||||||
world_info_case_sensitive: world_info_case_sensitive,
|
|
||||||
world_info_match_whole_words: world_info_match_whole_words,
|
|
||||||
world_info_character_strategy: world_info_character_strategy,
|
|
||||||
textgenerationwebui_settings: textgenerationwebui_settings,
|
textgenerationwebui_settings: textgenerationwebui_settings,
|
||||||
swipes: swipes,
|
swipes: swipes,
|
||||||
horde_settings: horde_settings,
|
horde_settings: horde_settings,
|
||||||
|
@ -5476,8 +5472,8 @@ async function getStatusNovel() {
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (data.error != true) {
|
if (data.error != true) {
|
||||||
novel_tier = data.tier;
|
setNovelData(data);
|
||||||
online_status = getNovelTier(novel_tier);
|
online_status = `${getNovelTier(data.tier)} (${getNovelMaxContextTokens()} context tokens)`;
|
||||||
}
|
}
|
||||||
resultCheckStatusNovel();
|
resultCheckStatusNovel();
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ const MODULE_NAME = 'expressions';
|
||||||
const UPDATE_INTERVAL = 2000;
|
const UPDATE_INTERVAL = 2000;
|
||||||
const FALLBACK_EXPRESSION = 'joy';
|
const FALLBACK_EXPRESSION = 'joy';
|
||||||
const DEFAULT_EXPRESSIONS = [
|
const DEFAULT_EXPRESSIONS = [
|
||||||
"live2d",
|
"talkinghead",
|
||||||
"admiration",
|
"admiration",
|
||||||
"amusement",
|
"amusement",
|
||||||
"anger",
|
"anger",
|
||||||
|
@ -396,7 +396,7 @@ function onExpressionsShowDefaultInput() {
|
||||||
async function unloadLiveChar() {
|
async function unloadLiveChar() {
|
||||||
try {
|
try {
|
||||||
const url = new URL(getApiUrl());
|
const url = new URL(getApiUrl());
|
||||||
url.pathname = '/api/live2d/unload';
|
url.pathname = '/api/talkinghead/unload';
|
||||||
const loadResponse = await doExtrasFetch(url);
|
const loadResponse = await doExtrasFetch(url);
|
||||||
if (!loadResponse.ok) {
|
if (!loadResponse.ok) {
|
||||||
throw new Error(loadResponse.statusText);
|
throw new Error(loadResponse.statusText);
|
||||||
|
@ -409,8 +409,8 @@ async function unloadLiveChar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadLiveChar() {
|
async function loadLiveChar() {
|
||||||
if (!modules.includes('live2d')) {
|
if (!modules.includes('talkinghead')) {
|
||||||
console.debug('live2d module is disabled');
|
console.debug('talkinghead module is disabled');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,22 +426,22 @@ async function loadLiveChar() {
|
||||||
spriteFolderName = expressionOverride.path;
|
spriteFolderName = expressionOverride.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
const live2dPath = `/characters/${encodeURIComponent(spriteFolderName)}/live2d.png`;
|
const talkingheadPath = `/characters/${encodeURIComponent(spriteFolderName)}/talkinghead.png`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const spriteResponse = await fetch(live2dPath);
|
const spriteResponse = await fetch(talkingheadPath);
|
||||||
|
|
||||||
if (!spriteResponse.ok) {
|
if (!spriteResponse.ok) {
|
||||||
throw new Error(spriteResponse.statusText);
|
throw new Error(spriteResponse.statusText);
|
||||||
}
|
}
|
||||||
|
|
||||||
const spriteBlob = await spriteResponse.blob();
|
const spriteBlob = await spriteResponse.blob();
|
||||||
const spriteFile = new File([spriteBlob], 'live2d.png', { type: 'image/png' });
|
const spriteFile = new File([spriteBlob], 'talkinghead.png', { type: 'image/png' });
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', spriteFile);
|
formData.append('file', spriteFile);
|
||||||
|
|
||||||
const url = new URL(getApiUrl());
|
const url = new URL(getApiUrl());
|
||||||
url.pathname = '/api/live2d/load';
|
url.pathname = '/api/talkinghead/load';
|
||||||
|
|
||||||
const loadResponse = await doExtrasFetch(url, {
|
const loadResponse = await doExtrasFetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -453,10 +453,10 @@ async function loadLiveChar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadResponseText = await loadResponse.text();
|
const loadResponseText = await loadResponse.text();
|
||||||
console.log(`Load live2d response: ${loadResponseText}`);
|
console.log(`Load talkinghead response: ${loadResponseText}`);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error loading live2d image: ${live2dPath} - ${error}`);
|
console.error(`Error loading talkinghead image: ${talkingheadPath} - ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,11 +468,11 @@ function handleImageChange() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extension_settings.expressions.live2d) {
|
if (extension_settings.expressions.talkinghead) {
|
||||||
// Method get IP of endpoint
|
// Method get IP of endpoint
|
||||||
const live2dResultFeedSrc = `${getApiUrl()}/api/live2d/result_feed`;
|
const talkingheadResultFeedSrc = `${getApiUrl()}/api/talkinghead/result_feed`;
|
||||||
$('#expression-holder').css({ display: '' });
|
$('#expression-holder').css({ display: '' });
|
||||||
if (imgElement.src !== live2dResultFeedSrc) {
|
if (imgElement.src !== talkingheadResultFeedSrc) {
|
||||||
const expressionImageElement = document.querySelector('.expression_list_image');
|
const expressionImageElement = document.querySelector('.expression_list_image');
|
||||||
|
|
||||||
if (expressionImageElement) {
|
if (expressionImageElement) {
|
||||||
|
@ -481,7 +481,7 @@ function handleImageChange() {
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
imgElement.src = live2dResultFeedSrc;
|
imgElement.src = talkingheadResultFeedSrc;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
@ -514,9 +514,9 @@ async function moduleWorker() {
|
||||||
imgElement.src = "";
|
imgElement.src = "";
|
||||||
|
|
||||||
//set checkbox to global var
|
//set checkbox to global var
|
||||||
$('#image_type_toggle').prop('checked', extension_settings.expressions.live2d);
|
$('#image_type_toggle').prop('checked', extension_settings.expressions.talkinghead);
|
||||||
if (extension_settings.expressions.live2d) {
|
if (extension_settings.expressions.talkinghead) {
|
||||||
setLive2dState(extension_settings.expressions.live2d);
|
settalkingheadState(extension_settings.expressions.talkinghead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,7 +622,7 @@ async function moduleWorker() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function live2dcheck() {
|
async function talkingheadcheck() {
|
||||||
const context = getContext();
|
const context = getContext();
|
||||||
let spriteFolderName = context.name2;
|
let spriteFolderName = context.name2;
|
||||||
const message = getLastCharacterMessage();
|
const message = getLastCharacterMessage();
|
||||||
|
@ -638,14 +638,14 @@ async function live2dcheck() {
|
||||||
try {
|
try {
|
||||||
await validateImages(spriteFolderName);
|
await validateImages(spriteFolderName);
|
||||||
|
|
||||||
let live2dObj = spriteCache[spriteFolderName].find(obj => obj.label === 'live2d');
|
let talkingheadObj = spriteCache[spriteFolderName].find(obj => obj.label === 'talkinghead');
|
||||||
let live2dPath_f = live2dObj ? live2dObj.path : null;
|
let talkingheadPath_f = talkingheadObj ? talkingheadObj.path : null;
|
||||||
|
|
||||||
if (live2dPath_f != null) {
|
if (talkingheadPath_f != null) {
|
||||||
//console.log("live2dPath_f " + live2dPath_f);
|
//console.log("talkingheadPath_f " + talkingheadPath_f);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
//console.log("live2dPath_f is null");
|
//console.log("talkingheadPath_f is null");
|
||||||
unloadLiveChar();
|
unloadLiveChar();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -654,15 +654,15 @@ async function live2dcheck() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLive2dState(switch_var) {
|
function settalkingheadState(switch_var) {
|
||||||
extension_settings.expressions.live2d = switch_var; // Store setting
|
extension_settings.expressions.talkinghead = switch_var; // Store setting
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
|
|
||||||
live2dcheck().then(result => {
|
talkingheadcheck().then(result => {
|
||||||
if (result) {
|
if (result) {
|
||||||
//console.log("Live2d exists!");
|
//console.log("talkinghead exists!");
|
||||||
|
|
||||||
if (extension_settings.expressions.live2d) {
|
if (extension_settings.expressions.talkinghead) {
|
||||||
loadLiveChar();
|
loadLiveChar();
|
||||||
} else {
|
} else {
|
||||||
unloadLiveChar();
|
unloadLiveChar();
|
||||||
|
@ -671,7 +671,7 @@ function setLive2dState(switch_var) {
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//console.log("Live2d does not exist.");
|
//console.log("talkinghead does not exist.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -863,7 +863,7 @@ async function getExpressionsList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setExpression(character, expression, force) {
|
async function setExpression(character, expression, force) {
|
||||||
if (!extension_settings.expressions.live2d) {
|
if (!extension_settings.expressions.talkinghead) {
|
||||||
console.debug('entered setExpressions');
|
console.debug('entered setExpressions');
|
||||||
await validateImages(character);
|
await validateImages(character);
|
||||||
const img = $('img.expression');
|
const img = $('img.expression');
|
||||||
|
@ -976,14 +976,14 @@ async function setExpression(character, expression, force) {
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
live2dcheck().then(result => {
|
talkingheadcheck().then(result => {
|
||||||
if (result) {
|
if (result) {
|
||||||
// Find the <img> element with id="expression-image" and class="expression"
|
// Find the <img> element with id="expression-image" and class="expression"
|
||||||
const imgElement = document.querySelector('img#expression-image.expression');
|
const imgElement = document.querySelector('img#expression-image.expression');
|
||||||
//console.log("searching");
|
//console.log("searching");
|
||||||
if (imgElement) {
|
if (imgElement) {
|
||||||
//console.log("setting value");
|
//console.log("setting value");
|
||||||
imgElement.src = getApiUrl() + '/api/live2d/result_feed';
|
imgElement.src = getApiUrl() + '/api/talkinghead/result_feed';
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1255,7 +1255,7 @@ function setExpressionOverrideHtml(forceClear = false) {
|
||||||
<label class="switch">
|
<label class="switch">
|
||||||
<input id="image_type_toggle" type="checkbox">
|
<input id="image_type_toggle" type="checkbox">
|
||||||
<span class="slider round"></span>
|
<span class="slider round"></span>
|
||||||
<label for="image_type_toggle">Image Type - Live2d (extras)</label>
|
<label for="image_type_toggle">Image Type - talkinghead (extras)</label>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="offline_mode">
|
<div class="offline_mode">
|
||||||
|
@ -1305,7 +1305,7 @@ function setExpressionOverrideHtml(forceClear = false) {
|
||||||
$('.expression_settings').hide();
|
$('.expression_settings').hide();
|
||||||
|
|
||||||
$('#image_type_toggle').on('click', function () {
|
$('#image_type_toggle').on('click', function () {
|
||||||
setLive2dState(this.checked);
|
settalkingheadState(this.checked);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { SystemTtsProvider } from './system.js'
|
||||||
import { NovelTtsProvider } from './novel.js'
|
import { NovelTtsProvider } from './novel.js'
|
||||||
import { power_user } from '../../power-user.js'
|
import { power_user } from '../../power-user.js'
|
||||||
import { rvcVoiceConversion } from "../rvc/index.js"
|
import { rvcVoiceConversion } from "../rvc/index.js"
|
||||||
|
export { talkingAnimation };
|
||||||
|
|
||||||
const UPDATE_INTERVAL = 1000
|
const UPDATE_INTERVAL = 1000
|
||||||
|
|
||||||
|
@ -171,12 +172,13 @@ function talkingAnimation(switchValue) {
|
||||||
if (switchValue !== storedvalue) {
|
if (switchValue !== storedvalue) {
|
||||||
try {
|
try {
|
||||||
console.log(animationType + " Talking Animation");
|
console.log(animationType + " Talking Animation");
|
||||||
doExtrasFetch(`${apiUrl}/api/live2d/${animationType}_talking`);
|
doExtrasFetch(`${apiUrl}/api/talkinghead/${animationType}_talking`);
|
||||||
storedvalue = switchValue; // Update the storedvalue to the current switchValue
|
storedvalue = switchValue; // Update the storedvalue to the current switchValue
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Handle the error here or simply ignore it to prevent logging
|
// Handle the error here or simply ignore it to prevent logging
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updateUiAudioPlayState()
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetTtsPlayback() {
|
function resetTtsPlayback() {
|
||||||
|
@ -305,10 +307,8 @@ function updateUiAudioPlayState() {
|
||||||
// Give user feedback that TTS is active by setting the stop icon if processing or playing
|
// Give user feedback that TTS is active by setting the stop icon if processing or playing
|
||||||
if (!audioElement.paused || isTtsProcessing()) {
|
if (!audioElement.paused || isTtsProcessing()) {
|
||||||
img = 'fa-solid fa-stop-circle extensionsMenuExtensionButton'
|
img = 'fa-solid fa-stop-circle extensionsMenuExtensionButton'
|
||||||
talkingAnimation(true)
|
|
||||||
} else {
|
} else {
|
||||||
img = 'fa-solid fa-circle-play extensionsMenuExtensionButton'
|
img = 'fa-solid fa-circle-play extensionsMenuExtensionButton'
|
||||||
talkingAnimation(false)
|
|
||||||
}
|
}
|
||||||
$('#tts_media_control').attr('class', img);
|
$('#tts_media_control').attr('class', img);
|
||||||
} else {
|
} else {
|
||||||
|
@ -345,6 +345,7 @@ function completeCurrentAudioJob() {
|
||||||
audioQueueProcessorReady = true
|
audioQueueProcessorReady = true
|
||||||
currentAudioJob = null
|
currentAudioJob = null
|
||||||
lastAudioPosition = 0
|
lastAudioPosition = 0
|
||||||
|
talkingAnimation(false) //stop lip animation
|
||||||
// updateUiPlayState();
|
// updateUiPlayState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { isMobile } from "../../RossAscends-mods.js";
|
import { isMobile } from "../../RossAscends-mods.js";
|
||||||
import { getPreviewString } from "./index.js";
|
import { getPreviewString } from "./index.js";
|
||||||
|
import { talkingAnimation } from './index.js';
|
||||||
|
|
||||||
export { SystemTtsProvider }
|
export { SystemTtsProvider }
|
||||||
|
|
||||||
|
@ -69,6 +70,7 @@ var speechUtteranceChunker = function (utt, settings, callback) {
|
||||||
//placing the speak invocation inside a callback fixes ordering and onend issues.
|
//placing the speak invocation inside a callback fixes ordering and onend issues.
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
speechSynthesis.speak(newUtt);
|
speechSynthesis.speak(newUtt);
|
||||||
|
talkingAnimation(true);
|
||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,6 +223,7 @@ class SystemTtsProvider {
|
||||||
//some code to execute when done
|
//some code to execute when done
|
||||||
resolve(silence);
|
resolve(silence);
|
||||||
console.log('System TTS done');
|
console.log('System TTS done');
|
||||||
|
talkingAnimation(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,16 @@ const nai_tiers = {
|
||||||
3: 'Opus',
|
3: 'Opus',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let novel_data = null;
|
||||||
|
|
||||||
|
export function setNovelData(data) {
|
||||||
|
novel_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNovelMaxContextTokens() {
|
||||||
|
return novel_data?.perks?.contextTokens;
|
||||||
|
}
|
||||||
|
|
||||||
function getNovelTier(tier) {
|
function getNovelTier(tier) {
|
||||||
return nai_tiers[tier] ?? 'no_connection';
|
return nai_tiers[tier] ?? 'no_connection';
|
||||||
}
|
}
|
||||||
|
|
|
@ -722,10 +722,13 @@ function saveModelList(data) {
|
||||||
$('#model_openrouter_select').empty();
|
$('#model_openrouter_select').empty();
|
||||||
$('#model_openrouter_select').append($('<option>', { value: openrouter_website_model, text: 'Use OpenRouter website setting' }));
|
$('#model_openrouter_select').append($('<option>', { value: openrouter_website_model, text: 'Use OpenRouter website setting' }));
|
||||||
model_list.forEach((model) => {
|
model_list.forEach((model) => {
|
||||||
|
let tokens_dollar = parseFloat(1 / (1000 * model.pricing.prompt));
|
||||||
|
let tokens_rounded = (Math.round(tokens_dollar * 1000) / 1000).toFixed(0);
|
||||||
|
let model_description = `${model.id} | ${tokens_rounded}k t/$ | ${model.context_length} ctx`;
|
||||||
$('#model_openrouter_select').append(
|
$('#model_openrouter_select').append(
|
||||||
$('<option>', {
|
$('<option>', {
|
||||||
value: model.id,
|
value: model.id,
|
||||||
text: model.id,
|
text: model_description,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
$('#model_openrouter_select').val(oai_settings.openrouter_model).trigger('change');
|
$('#model_openrouter_select').val(oai_settings.openrouter_model).trigger('change');
|
||||||
|
|
|
@ -14,6 +14,7 @@ export {
|
||||||
world_info_case_sensitive,
|
world_info_case_sensitive,
|
||||||
world_info_match_whole_words,
|
world_info_match_whole_words,
|
||||||
world_info_character_strategy,
|
world_info_character_strategy,
|
||||||
|
world_info_budget_cap,
|
||||||
world_names,
|
world_names,
|
||||||
checkWorldInfo,
|
checkWorldInfo,
|
||||||
deleteWorldInfo,
|
deleteWorldInfo,
|
||||||
|
@ -37,6 +38,7 @@ let world_info_overflow_alert = false;
|
||||||
let world_info_case_sensitive = false;
|
let world_info_case_sensitive = false;
|
||||||
let world_info_match_whole_words = false;
|
let world_info_match_whole_words = false;
|
||||||
let world_info_character_strategy = world_info_insertion_strategy.character_first;
|
let world_info_character_strategy = world_info_insertion_strategy.character_first;
|
||||||
|
let world_info_budget_cap = 0;
|
||||||
const saveWorldDebounced = debounce(async (name, data) => await _save(name, data), 1000);
|
const saveWorldDebounced = debounce(async (name, data) => await _save(name, data), 1000);
|
||||||
const saveSettingsDebounced = debounce(() => {
|
const saveSettingsDebounced = debounce(() => {
|
||||||
Object.assign(world_info, { globalSelect: selected_world_info })
|
Object.assign(world_info, { globalSelect: selected_world_info })
|
||||||
|
@ -44,6 +46,20 @@ const saveSettingsDebounced = debounce(() => {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
const sortFn = (a, b) => b.order - a.order;
|
const sortFn = (a, b) => b.order - a.order;
|
||||||
|
|
||||||
|
export function getWorldInfoSettings() {
|
||||||
|
return {
|
||||||
|
world_info,
|
||||||
|
world_info_depth,
|
||||||
|
world_info_budget,
|
||||||
|
world_info_recursive,
|
||||||
|
world_info_overflow_alert,
|
||||||
|
world_info_case_sensitive,
|
||||||
|
world_info_match_whole_words,
|
||||||
|
world_info_character_strategy,
|
||||||
|
world_info_budget_cap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const world_info_position = {
|
const world_info_position = {
|
||||||
before: 0,
|
before: 0,
|
||||||
after: 1,
|
after: 1,
|
||||||
|
@ -80,6 +96,8 @@ function setWorldInfoSettings(settings, data) {
|
||||||
world_info_match_whole_words = Boolean(settings.world_info_match_whole_words);
|
world_info_match_whole_words = Boolean(settings.world_info_match_whole_words);
|
||||||
if (settings.world_info_character_strategy !== undefined)
|
if (settings.world_info_character_strategy !== undefined)
|
||||||
world_info_character_strategy = Number(settings.world_info_character_strategy);
|
world_info_character_strategy = Number(settings.world_info_character_strategy);
|
||||||
|
if (settings.world_info_budget_cap !== undefined)
|
||||||
|
world_info_budget_cap = Number(settings.world_info_budget_cap);
|
||||||
|
|
||||||
// Migrate old settings
|
// Migrate old settings
|
||||||
if (world_info_budget > 100) {
|
if (world_info_budget > 100) {
|
||||||
|
@ -113,6 +131,9 @@ function setWorldInfoSettings(settings, data) {
|
||||||
$(`#world_info_character_strategy option[value='${world_info_character_strategy}']`).prop('selected', true);
|
$(`#world_info_character_strategy option[value='${world_info_character_strategy}']`).prop('selected', true);
|
||||||
$("#world_info_character_strategy").val(world_info_character_strategy);
|
$("#world_info_character_strategy").val(world_info_character_strategy);
|
||||||
|
|
||||||
|
$("#world_info_budget_cap").val(world_info_budget_cap);
|
||||||
|
$("#world_info_budget_cap_counter").text(world_info_budget_cap);
|
||||||
|
|
||||||
world_names = data.world_names?.length ? data.world_names : [];
|
world_names = data.world_names?.length ? data.world_names : [];
|
||||||
|
|
||||||
// Add to existing selected WI if it exists
|
// Add to existing selected WI if it exists
|
||||||
|
@ -922,8 +943,14 @@ async function checkWorldInfo(chat, maxContext) {
|
||||||
let failedProbabilityChecks = new Set();
|
let failedProbabilityChecks = new Set();
|
||||||
let allActivatedText = '';
|
let allActivatedText = '';
|
||||||
|
|
||||||
const budget = Math.round(world_info_budget * maxContext / 100) || 1;
|
let budget = Math.round(world_info_budget * maxContext / 100) || 1;
|
||||||
console.debug(`Context size: ${maxContext}; WI budget: ${budget} (${world_info_budget}%)`);
|
|
||||||
|
if (world_info_budget_cap > 0 && budget > world_info_budget_cap) {
|
||||||
|
console.debug(`Budget ${budget} exceeds cap ${world_info_budget_cap}, using cap`);
|
||||||
|
budget = world_info_budget_cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug(`Context size: ${maxContext}; WI budget: ${budget} (max% = ${world_info_budget}%, cap = ${world_info_budget_cap})`);
|
||||||
const sortedEntries = await getSortedEntries();
|
const sortedEntries = await getSortedEntries();
|
||||||
|
|
||||||
if (sortedEntries.length === 0) {
|
if (sortedEntries.length === 0) {
|
||||||
|
@ -1515,6 +1542,12 @@ jQuery(() => {
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#world_info_budget_cap').on('input', function () {
|
||||||
|
world_info_budget_cap = Number($(this).val());
|
||||||
|
$("#world_info_budget_cap_counter").text(world_info_budget_cap);
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
$('#world_button').on('click', async function () {
|
$('#world_button').on('click', async function () {
|
||||||
const chid = $('#set_character_world').data('chid');
|
const chid = $('#set_character_world').data('chid');
|
||||||
|
|
||||||
|
|
|
@ -2259,6 +2259,11 @@ grammarly-extension {
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.budget_cap_note {
|
||||||
|
flex-basis: 100%;
|
||||||
|
line-height: 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
#world_popup {
|
#world_popup {
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
|
|
18
server.js
18
server.js
|
@ -2964,8 +2964,22 @@ app.post("/getstatus_openai", jsonParser, function (request, response_getstatus_
|
||||||
client.get(api_url + "/models", args, function (data, response) {
|
client.get(api_url + "/models", args, function (data, response) {
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
response_getstatus_openai.send(data);
|
response_getstatus_openai.send(data);
|
||||||
const modelIds = data?.data?.map(x => x.id)?.sort();
|
if (request.body.use_openrouter) {
|
||||||
console.log('Available OpenAI models:', modelIds);
|
let models = [];
|
||||||
|
data.data.forEach(model => {
|
||||||
|
const context_length = model.context_length;
|
||||||
|
const tokens_dollar = parseFloat(1 / (1000 * model.pricing.prompt));
|
||||||
|
const tokens_rounded = (Math.round(tokens_dollar * 1000) / 1000).toFixed(0);
|
||||||
|
models[model.id] = {
|
||||||
|
tokens_per_dollar: tokens_rounded + 'k',
|
||||||
|
context_length: context_length,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
console.log('Available OpenRouter models:', models);
|
||||||
|
} else {
|
||||||
|
const modelIds = data?.data?.map(x => x.id)?.sort();
|
||||||
|
console.log('Available OpenAI models:', modelIds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (response.statusCode == 401) {
|
if (response.statusCode == 401) {
|
||||||
console.log('Access Token is incorrect.');
|
console.log('Access Token is incorrect.');
|
||||||
|
|
|
@ -165,7 +165,7 @@ async function loadStatsFile(chatsPath, charactersPath) {
|
||||||
*/
|
*/
|
||||||
async function saveStatsToFile() {
|
async function saveStatsToFile() {
|
||||||
if (charStats.timestamp > lastSaveTimestamp) {
|
if (charStats.timestamp > lastSaveTimestamp) {
|
||||||
console.debug("Saving stats to file...");
|
//console.debug("Saving stats to file...");
|
||||||
await writeFile(statsFilePath, JSON.stringify(charStats));
|
await writeFile(statsFilePath, JSON.stringify(charStats));
|
||||||
lastSaveTimestamp = Date.now();
|
lastSaveTimestamp = Date.now();
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue