Merge branch 'staging' of https://github.com/Cohee1207/SillyTavern into staging

This commit is contained in:
RossAscends 2023-11-29 03:35:34 +09:00
commit 9145406522
8 changed files with 125 additions and 21 deletions

View File

@ -216,9 +216,9 @@
<div id="pro-settings-block" class="flex-container gap10h5v justifyCenter">
<div id="amount_gen_block" class="alignitemscenter flex-container marginBot5 flexFlowColumn flexBasis48p flexGrow flexShrink gap0">
<small data-i18n="response legth(tokens)">Response (tokens)</small>
<input class="neo-range-slider" type="range" id="amount_gen" name="volume" min="16" max="1024" step="1">
<input class="neo-range-slider" type="range" id="amount_gen" name="volume" min="16" max="2048" step="1">
<div data-randomization-disabled="true" class="wide100p">
<input class="neo-range-input" type="number" min="16" max="1024" step="1" data-for="amount_gen" id="amount_gen_counter">
<input class="neo-range-input" type="number" min="16" max="2048" step="1" data-for="amount_gen" id="amount_gen_counter">
</div>
<div id="streaming_textgenerationwebui_block" class="flex-container alignitemscenter justifyCenter marginTop5">
<label class="checkbox_label" for="streaming_textgenerationwebui">

View File

@ -209,7 +209,7 @@ async function visualNovelUpdateLayers(container) {
const containerWidth = container.width();
const pivotalPoint = containerWidth * 0.5;
let images = $('.expression-holder');
let images = $('#visual-novel-wrapper .expression-holder');
let imagesWidth = [];
images.sort(sortFunction).each(function () {

View File

@ -68,7 +68,7 @@
}
.ctx-menu {
position: fixed;
position: absolute;
overflow: visible;
}
@ -110,4 +110,4 @@
.list-group .list-group-item.ctx-item {
padding: 1em;
}
}
}

View File

@ -508,7 +508,7 @@ async function processTtsQueue() {
}
// Collapse newlines and spaces into single space
text = text.replace(/\s+/g, ' ');
text = text.replace(/\s+/g, ' ').trim();
console.log(`TTS: ${text}`)
const char = currentTtsJob.name

View File

@ -32,6 +32,7 @@ class SileroTtsProvider {
// Used when provider settings are updated from UI
this.settings.provider_endpoint = $('#silero_tts_endpoint').val()
saveTtsProviderSettings()
this.refreshSession()
}
async loadSettings(settings) {
@ -43,8 +44,8 @@ class SileroTtsProvider {
// Only accept keys defined in defaultSettings
this.settings = this.defaultSettings
for (const key in settings){
if (key in this.settings){
for (const key in settings) {
if (key in this.settings) {
this.settings[key] = settings[key]
} else {
throw `Invalid setting passed to TTS Provider: ${key}`
@ -63,7 +64,8 @@ class SileroTtsProvider {
}, 2000);
$('#silero_tts_endpoint').val(this.settings.provider_endpoint)
$('#silero_tts_endpoint').on("input", () => {this.onSettingsChange()})
$('#silero_tts_endpoint').on("input", () => { this.onSettingsChange() })
this.refreshSession()
await this.checkReady()
@ -71,7 +73,7 @@ class SileroTtsProvider {
}
// Perform a simple readiness check by trying to fetch voiceIds
async checkReady(){
async checkReady() {
await this.fetchTtsVoiceObjects()
}
@ -79,6 +81,10 @@ class SileroTtsProvider {
return
}
async refreshSession() {
await this.initSession()
}
//#################//
// TTS Interfaces //
//#################//
@ -96,7 +102,7 @@ class SileroTtsProvider {
return match
}
async generateTts(text, voiceId){
async generateTts(text, voiceId) {
const response = await this.fetchTtsGeneration(text, voiceId)
return response
}
@ -121,11 +127,12 @@ class SileroTtsProvider {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache' // Added this line to disable caching of file so new files are always played - Rolyat 7/7/23
'Cache-Control': 'no-cache' // Added this line to disable caching of file so new files are always played - Rolyat 7/7/23
},
body: JSON.stringify({
"text": inputText,
"speaker": voiceId
"speaker": voiceId,
"session": "sillytavern"
})
}
)
@ -136,6 +143,31 @@ class SileroTtsProvider {
return response
}
async initSession() {
console.info(`Silero TTS: requesting new session`);
try {
const response = await doExtrasFetch(
`${this.settings.provider_endpoint}/session`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
},
body: JSON.stringify({
"path": "sillytavern",
}),
}
)
if (!response.ok && response.status !== 404) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
} catch (error) {
console.info('Silero TTS: endpoint not available', error);
}
}
// Interface not used by Silero TTS
async fetchTtsFromHistory(history_item_id) {
return Promise.resolve(history_item_id);

View File

@ -20,10 +20,12 @@ class XTTSTtsProvider {
*/
processText(text) {
// Replace fancy ellipsis with "..."
text = text.replace(/…/g, '...')
text = text.replace(/…/g, '...');
// Remove quotes
text = text.replace(/["“”‘’]/g, '');
// Replace multiple "." with single "."
text = text.replace(/\.+/g, '.')
return text
text = text.replace(/\.+/g, '.');
return text;
}
languageLabels = {

View File

@ -49,8 +49,8 @@ export {
};
export const MAX_CONTEXT_DEFAULT = 8192;
const MAX_CONTEXT_UNLOCKED = 65536;
const unlockedMaxContextStep = 1;
const MAX_CONTEXT_UNLOCKED = 200 * 1000;
const unlockedMaxContextStep = 256;
const maxContextMin = 512;
const maxContextStep = 1;

View File

@ -57,7 +57,7 @@ function addGlobalVariable(name, value) {
const currentValue = getGlobalVariable(name) || 0;
const increment = Number(value);
if (isNaN(increment)|| isNaN(Number(currentValue))) {
if (isNaN(increment) || isNaN(Number(currentValue))) {
const stringValue = String(currentValue || '') + value;
setGlobalVariable(name, stringValue);
return stringValue;
@ -73,6 +73,27 @@ function addGlobalVariable(name, value) {
return newValue;
}
function incrementLocalVariable(name) {
return addLocalVariable(name, 1);
}
function incrementGlobalVariable(name) {
return addGlobalVariable(name, 1);
}
function decrementLocalVariable(name) {
return addLocalVariable(name, -1);
}
function decrementGlobalVariable(name) {
return addGlobalVariable(name, -1);
}
/**
* Resolves a variable name to its value or returns the string as is if the variable does not exist.
* @param {string} name Variable name
* @returns {string} Variable value or the string literal
*/
export function resolveVariable(name) {
if (existsLocalVariable(name)) {
return getLocalVariable(name);
@ -193,16 +214,34 @@ async function ifCallback(args, command) {
return '';
}
/**
* Checks if a local variable exists.
* @param {string} name Local variable name
* @returns {boolean} True if the local variable exists, false otherwise
*/
function existsLocalVariable(name) {
return chat_metadata.variables && chat_metadata.variables[name] !== undefined;
}
/**
* Checks if a global variable exists.
* @param {string} name Global variable name
* @returns {boolean} True if the global variable exists, false otherwise
*/
function existsGlobalVariable(name) {
return extension_settings.variables.global && extension_settings.variables.global[name] !== undefined;
}
/**
* Parses boolean operands from command arguments.
* @param {object} args Command arguments
* @returns {{a: string | number, b: string | number, rule: string}} Boolean operands
*/
function parseBooleanOperands(args) {
// Resultion order: numeric literal, local variable, global variable, string literal
// Resolution order: numeric literal, local variable, global variable, string literal
/**
* @param {string} operand Boolean operand candidate
*/
function getOperand(operand) {
if (operand === undefined) {
return '';
@ -235,6 +274,13 @@ function parseBooleanOperands(args) {
return { a: left, b: right, rule };
}
/**
* Evaluates a boolean comparison rule.
* @param {string} rule Boolean comparison rule
* @param {string|number} a The left operand
* @param {string|number} b The right operand
* @returns {boolean} True if the rule yields true, false otherwise
*/
function evalBoolean(rule, a, b) {
if (!rule) {
toastr.warning('The rule must be specified for the boolean comparison.', 'Invalid command');
@ -299,6 +345,11 @@ function evalBoolean(rule, a, b) {
return result;
}
/**
* Executes a slash command from a string (may be enclosed in quotes) and returns the result.
* @param {string} command Command to execute. May contain escaped macro and batch separators.
* @returns {Promise<string>} Pipe result
*/
async function executeSubCommands(command) {
if (command.startsWith('"')) {
command = command.slice(1);
@ -318,6 +369,11 @@ async function executeSubCommands(command) {
return result?.pipe || '';
}
/**
* Deletes a local variable.
* @param {string} name Variable name to delete
* @returns {string} Empty string
*/
function deleteLocalVariable(name) {
if (!existsLocalVariable(name)) {
console.warn(`The local variable "${name}" does not exist.`);
@ -329,6 +385,11 @@ function deleteLocalVariable(name) {
return '';
}
/**
* Deletes a global variable.
* @param {string} name Variable name to delete
* @returns {string} Empty string
*/
function deleteGlobalVariable(name) {
if (!existsGlobalVariable(name)) {
console.warn(`The global variable "${name}" does not exist.`);
@ -340,6 +401,11 @@ function deleteGlobalVariable(name) {
return '';
}
/**
* Parses a series of numeric values from a string.
* @param {string} value A space-separated list of numeric values or variable names
* @returns {number[]} An array of numeric values
*/
function parseNumericSeries(value) {
if (typeof value === 'number') {
return [value];
@ -349,7 +415,7 @@ function parseNumericSeries(value) {
.split(' ')
.map(i => i.trim())
.filter(i => i !== '')
.map(i => isNaN(Number(i)) ? resolveVariable(i) : Number(i))
.map(i => isNaN(Number(i)) ? Number(resolveVariable(i)) : Number(i))
.filter(i => !isNaN(i));
return array;
@ -451,6 +517,10 @@ export function registerVariableCommands() {
registerSlashCommand('setglobalvar', (args, value) => setGlobalVariable(args.key || args.name, value), [], '<span class="monospace">key=varname (value)</span> set a global variable value and pass it down the pipe, e.g. <tt>/setglobalvar key=color green</tt>', true, true);
registerSlashCommand('getglobalvar', (_, value) => getGlobalVariable(value), [], '<span class="monospace">(key)</span> get a global variable value and pass it down the pipe, e.g. <tt>/getglobalvar height</tt>', true, true);
registerSlashCommand('addglobalvar', (args, value) => addGlobalVariable(args.key || args.name, value), [], '<span class="monospace">key=varname (increment)</span> add a value to a global variable and pass the result down the pipe, e.g. <tt>/addglobalvar score 10</tt>', true, true);
registerSlashCommand('incvar', (_, value) => incrementLocalVariable(value), [], '<span class="monospace">(key)</span> increment a local variable by 1 and pass the result down the pipe, e.g. <tt>/incvar score</tt>', true, true);
registerSlashCommand('decvar', (_, value) => decrementLocalVariable(value), [], '<span class="monospace">(key)</span> decrement a local variable by 1 and pass the result down the pipe, e.g. <tt>/decvar score</tt>', true, true);
registerSlashCommand('incglobalvar', (_, value) => incrementGlobalVariable(value), [], '<span class="monospace">(key)</span> increment a global variable by 1 and pass the result down the pipe, e.g. <tt>/incglobalvar score</tt>', true, true);
registerSlashCommand('decglobalvar', (_, value) => decrementGlobalVariable(value), [], '<span class="monospace">(key)</span> decrement a global variable by 1 and pass the result down the pipe, e.g. <tt>/decglobalvar score</tt>', true, true);
registerSlashCommand('if', ifCallback, [], '<span class="monospace">left=varname1 right=varname2 rule=comparison else="(alt.command)" "(command)"</span> compare the value of the left operand "a" with the value of the right operand "b", and if the condition yields true, then execute any valid slash command enclosed in quotes and pass the result of the command execution down the pipe. Numeric values and string literals for left and right operands supported. Available rules: gt => a > b, gte => a >= b, lt => a < b, lte => a <= b, eq => a == b, neq => a != b, not => !a, in (strings) => a includes b, nin (strings) => a not includes b, e.g. <tt>/if left=score right=10 rule=gte "/speak You win"</tt> triggers a /speak command if the value of "score" is greater or equals 10.', true, true);
registerSlashCommand('while', whileCallback, [], '<span class="monospace">left=varname1 right=varname2 rule=comparison "(command)"</span> compare the value of the left operand "a" with the value of the right operand "b", and if the condition yields true, then execute any valid slash command enclosed in quotes. Numeric values and string literals for left and right operands supported. Available rules: gt => a > b, gte => a >= b, lt => a < b, lte => a <= b, eq => a == b, neq => a != b, not => !a, in (strings) => a includes b, nin (strings) => a not includes b, e.g. <tt>/setvar key=i 0 | /while left=i right=10 rule=let "/addvar key=i 1"</tt> adds 1 to the value of "i" until it reaches 10. Loops are limited to 100 iterations by default, pass guard=off to disable.', true, true);
registerSlashCommand('flushvar', (_, value) => deleteLocalVariable(value), [], '<span class="monospace">(key)</span> delete a local variable, e.g. <tt>/flushvar score</tt>', true, true);