mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge pull request #3382 from SillyTavern/staging
Staging into reasoning-regex
This commit is contained in:
@ -6093,6 +6093,19 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes,
|
||||
return { type, getMessage };
|
||||
}
|
||||
|
||||
export function syncCurrentSwipeInfoExtras() {
|
||||
if (!chat.length) {
|
||||
return;
|
||||
}
|
||||
const currentMessage = chat[chat.length - 1];
|
||||
if (currentMessage && Array.isArray(currentMessage.swipe_info) && typeof currentMessage.swipe_id === 'number') {
|
||||
const swipeInfo = currentMessage.swipe_info[currentMessage.swipe_id];
|
||||
if (swipeInfo && typeof swipeInfo === 'object') {
|
||||
swipeInfo.extra = structuredClone(currentMessage.extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function saveImageToMessage(img, mes) {
|
||||
if (mes && img.image) {
|
||||
if (!mes.extra || typeof mes.extra !== 'object') {
|
||||
@ -8524,6 +8537,9 @@ function swipe_left() { // when we swipe left..but no generation.
|
||||
streamingProcessor.onStopStreaming();
|
||||
}
|
||||
|
||||
// Make sure ad-hoc changes to extras are saved before swiping away
|
||||
syncCurrentSwipeInfoExtras();
|
||||
|
||||
const swipe_duration = 120;
|
||||
const swipe_range = '700px';
|
||||
chat[chat.length - 1]['swipe_id']--;
|
||||
@ -8659,6 +8675,9 @@ const swipe_right = () => {
|
||||
return unblockGeneration();
|
||||
}
|
||||
|
||||
// Make sure ad-hoc changes to extras are saved before swiping away
|
||||
syncCurrentSwipeInfoExtras();
|
||||
|
||||
const swipe_duration = 200;
|
||||
const swipe_range = 700;
|
||||
//console.log(swipe_range);
|
||||
|
@ -566,7 +566,7 @@ export function initAuthorsNote() {
|
||||
namedArgumentList: [],
|
||||
unnamedArgumentList: [
|
||||
new SlashCommandArgument(
|
||||
'position', [ARGUMENT_TYPE.STRING], false, false, null, ['system', 'user', 'assistant'],
|
||||
'role', [ARGUMENT_TYPE.STRING], false, false, null, ['system', 'user', 'assistant'],
|
||||
),
|
||||
],
|
||||
helpString: `
|
||||
|
@ -30,6 +30,7 @@ const CC_COMMANDS = [
|
||||
'api-url',
|
||||
'model',
|
||||
'proxy',
|
||||
'stop-strings',
|
||||
];
|
||||
|
||||
const TC_COMMANDS = [
|
||||
@ -43,6 +44,7 @@ const TC_COMMANDS = [
|
||||
'context',
|
||||
'instruct-state',
|
||||
'tokenizer',
|
||||
'stop-strings',
|
||||
];
|
||||
|
||||
const FANCY_NAMES = {
|
||||
@ -57,6 +59,7 @@ const FANCY_NAMES = {
|
||||
'instruct': 'Instruct Template',
|
||||
'context': 'Context Template',
|
||||
'tokenizer': 'Tokenizer',
|
||||
'stop-strings': 'Custom Stopping Strings',
|
||||
};
|
||||
|
||||
/**
|
||||
@ -138,6 +141,7 @@ const profilesProvider = () => [
|
||||
* @property {string} [context] Context Template
|
||||
* @property {string} [instruct-state] Instruct Mode
|
||||
* @property {string} [tokenizer] Tokenizer
|
||||
* @property {string} [stop-strings] Custom Stopping Strings
|
||||
* @property {string[]} [exclude] Commands to exclude
|
||||
*/
|
||||
|
||||
|
@ -30,6 +30,7 @@ import { GoogleTranslateTtsProvider } from './google-translate.js';
|
||||
export { talkingAnimation };
|
||||
|
||||
const UPDATE_INTERVAL = 1000;
|
||||
const wrapper = new ModuleWorkerWrapper(moduleWorker);
|
||||
|
||||
let voiceMapEntries = [];
|
||||
let voiceMap = {}; // {charName:voiceid, charName2:voiceid2}
|
||||
@ -120,7 +121,7 @@ async function onNarrateOneMessage() {
|
||||
}
|
||||
|
||||
resetTtsPlayback();
|
||||
ttsJobQueue.push(message);
|
||||
processAndQueueTtsMessage(message);
|
||||
moduleWorker();
|
||||
}
|
||||
|
||||
@ -147,7 +148,7 @@ async function onNarrateText(args, text) {
|
||||
}
|
||||
|
||||
resetTtsPlayback();
|
||||
ttsJobQueue.push({ mes: text, name: name });
|
||||
processAndQueueTtsMessage({ mes: text, name: name });
|
||||
await moduleWorker();
|
||||
|
||||
// Return back to the chat voices
|
||||
@ -220,6 +221,36 @@ function isTtsProcessing() {
|
||||
return processing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a message into lines and adds each non-empty line to the TTS job queue.
|
||||
* @param {Object} message - The message object to be processed.
|
||||
* @param {string} message.mes - The text of the message to be split into lines.
|
||||
* @param {string} message.name - The name associated with the message.
|
||||
* @returns {void}
|
||||
*/
|
||||
function processAndQueueTtsMessage(message) {
|
||||
if (!extension_settings.tts.narrate_by_paragraphs) {
|
||||
ttsJobQueue.push(message);
|
||||
return;
|
||||
}
|
||||
|
||||
const lines = message.mes.split('\n');
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
|
||||
if (line.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ttsJobQueue.push(
|
||||
Object.assign({}, message, {
|
||||
mes: line,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function debugTtsPlayback() {
|
||||
console.log(JSON.stringify(
|
||||
{
|
||||
@ -350,7 +381,7 @@ function onAudioControlClicked() {
|
||||
talkingAnimation(false);
|
||||
} else {
|
||||
// Default play behavior if not processing or playing is to play the last message.
|
||||
ttsJobQueue.push(context.chat[context.chat.length - 1]);
|
||||
processAndQueueTtsMessage(context.chat[context.chat.length - 1]);
|
||||
}
|
||||
updateUiAudioPlayState();
|
||||
}
|
||||
@ -376,6 +407,7 @@ function completeCurrentAudioJob() {
|
||||
currentAudioJob = null;
|
||||
talkingAnimation(false); //stop lip animation
|
||||
// updateUiPlayState();
|
||||
wrapper.update();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -466,7 +498,7 @@ async function processTtsQueue() {
|
||||
}
|
||||
|
||||
if (extension_settings.tts.skip_tags) {
|
||||
text = text.replace(/<.*?>.*?<\/.*?>/g, '').trim();
|
||||
text = text.replace(/<.*?>[\s\S]*?<\/.*?>/g, '').trim();
|
||||
}
|
||||
|
||||
if (!extension_settings.tts.pass_asterisks) {
|
||||
@ -569,6 +601,7 @@ function loadSettings() {
|
||||
$('#tts_narrate_quoted').prop('checked', extension_settings.tts.narrate_quoted_only);
|
||||
$('#tts_auto_generation').prop('checked', extension_settings.tts.auto_generation);
|
||||
$('#tts_periodic_auto_generation').prop('checked', extension_settings.tts.periodic_auto_generation);
|
||||
$('#tts_narrate_by_paragraphs').prop('checked', extension_settings.tts.narrate_by_paragraphs);
|
||||
$('#tts_narrate_translated_only').prop('checked', extension_settings.tts.narrate_translated_only);
|
||||
$('#tts_narrate_user').prop('checked', extension_settings.tts.narrate_user);
|
||||
$('#tts_pass_asterisks').prop('checked', extension_settings.tts.pass_asterisks);
|
||||
@ -638,6 +671,11 @@ function onPeriodicAutoGenerationClick() {
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
function onNarrateByParagraphsClick() {
|
||||
extension_settings.tts.narrate_by_paragraphs = !!$('#tts_narrate_by_paragraphs').prop('checked');
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
|
||||
function onNarrateDialoguesClick() {
|
||||
extension_settings.tts.narrate_dialogues_only = !!$('#tts_narrate_dialogues').prop('checked');
|
||||
@ -816,7 +854,12 @@ async function onMessageEvent(messageId, lastCharIndex) {
|
||||
lastChatId = context.chatId;
|
||||
|
||||
console.debug(`Adding message from ${message.name} for TTS processing: "${message.mes}"`);
|
||||
|
||||
if (extension_settings.tts.periodic_auto_generation) {
|
||||
ttsJobQueue.push(message);
|
||||
} else {
|
||||
processAndQueueTtsMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
async function onMessageDeleted() {
|
||||
@ -1156,6 +1199,7 @@ jQuery(async function () {
|
||||
$('#tts_pass_asterisks').on('click', onPassAsterisksClick);
|
||||
$('#tts_auto_generation').on('click', onAutoGenerationClick);
|
||||
$('#tts_periodic_auto_generation').on('click', onPeriodicAutoGenerationClick);
|
||||
$('#tts_narrate_by_paragraphs').on('click', onNarrateByParagraphsClick);
|
||||
$('#tts_narrate_user').on('click', onNarrateUserClick);
|
||||
|
||||
$('#playback_rate').on('input', function () {
|
||||
@ -1177,7 +1221,6 @@ jQuery(async function () {
|
||||
loadSettings(); // Depends on Extension Controls and loadTtsProvider
|
||||
loadTtsProvider(extension_settings.tts.currentProvider); // No dependencies
|
||||
addAudioControl(); // Depends on Extension Controls
|
||||
const wrapper = new ModuleWorkerWrapper(moduleWorker);
|
||||
setInterval(wrapper.update.bind(wrapper), UPDATE_INTERVAL); // Init depends on all the things
|
||||
eventSource.on(event_types.MESSAGE_SWIPED, resetTtsPlayback);
|
||||
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);
|
||||
|
@ -30,6 +30,10 @@
|
||||
<input type="checkbox" id="tts_periodic_auto_generation">
|
||||
<small data-i18n="Narrate by paragraphs (when streaming)">Narrate by paragraphs (when streaming)</small>
|
||||
</label>
|
||||
<label class="checkbox_label" for="tts_narrate_by_paragraphs">
|
||||
<input type="checkbox" id="tts_narrate_by_paragraphs">
|
||||
<small data-i18n="Narrate by paragraphs (when not streaming)">Narrate by paragraphs (when not streaming)</small>
|
||||
</label>
|
||||
<label class="checkbox_label" for="tts_narrate_quoted">
|
||||
<input type="checkbox" id="tts_narrate_quoted">
|
||||
<small data-i18n="Only narrate quotes">Only narrate "quotes"</small>
|
||||
|
@ -4072,4 +4072,45 @@ $(document).ready(() => {
|
||||
],
|
||||
helpString: 'activates a movingUI preset by name',
|
||||
}));
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||
name: 'stop-strings',
|
||||
aliases: ['stopping-strings', 'custom-stopping-strings', 'custom-stop-strings'],
|
||||
helpString: `
|
||||
<div>
|
||||
Sets a list of custom stopping strings. Gets the list if no value is provided.
|
||||
</div>
|
||||
<div>
|
||||
<strong>Examples:</strong>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Value must be a JSON-serialized array: <pre><code class="language-stscript">/stop-strings ["goodbye", "farewell"]</code></pre></li>
|
||||
<li>Pipe characters must be escaped with a backslash: <pre><code class="language-stscript">/stop-strings ["left\\|right"]</code></pre></li>
|
||||
</ul>
|
||||
`,
|
||||
returns: ARGUMENT_TYPE.LIST,
|
||||
unnamedArgumentList: [
|
||||
SlashCommandArgument.fromProps({
|
||||
description: 'list of strings',
|
||||
typeList: [ARGUMENT_TYPE.LIST],
|
||||
acceptsMultiple: false,
|
||||
isRequired: false,
|
||||
}),
|
||||
],
|
||||
callback: (_, value) => {
|
||||
if (String(value ?? '').trim()) {
|
||||
const parsedValue = ((x) => { try { return JSON.parse(x.toString()); } catch { return null; } })(value);
|
||||
if (!parsedValue || !Array.isArray(parsedValue)) {
|
||||
throw new Error('Invalid list format. The value must be a JSON-serialized array of strings.');
|
||||
}
|
||||
parsedValue.forEach((item, index) => {
|
||||
parsedValue[index] = String(item);
|
||||
});
|
||||
power_user.custom_stopping_strings = JSON.stringify(parsedValue);
|
||||
$('#custom_stopping_strings').val(power_user.custom_stopping_strings);
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
return power_user.custom_stopping_strings;
|
||||
},
|
||||
}));
|
||||
});
|
||||
|
@ -147,7 +147,7 @@ function registerReasoningSlashCommands() {
|
||||
}),
|
||||
],
|
||||
callback: async (args, value) => {
|
||||
const messageId = !isNaN(Number(args[0])) ? Number(args[0]) : chat.length - 1;
|
||||
const messageId = !isNaN(Number(args.at)) ? Number(args.at) : chat.length - 1;
|
||||
const message = chat[messageId];
|
||||
if (!message?.extra) {
|
||||
return '';
|
||||
|
@ -42,6 +42,7 @@ import {
|
||||
showMoreMessages,
|
||||
stopGeneration,
|
||||
substituteParams,
|
||||
syncCurrentSwipeInfoExtras,
|
||||
system_avatar,
|
||||
system_message_types,
|
||||
this_chid,
|
||||
@ -2814,8 +2815,11 @@ async function addSwipeCallback(args, value) {
|
||||
const newSwipeId = lastMessage.swipes.length - 1;
|
||||
|
||||
if (isTrueBoolean(args.switch)) {
|
||||
// Make sure ad-hoc changes to extras are saved before swiping away
|
||||
syncCurrentSwipeInfoExtras();
|
||||
lastMessage.swipe_id = newSwipeId;
|
||||
lastMessage.mes = lastMessage.swipes[newSwipeId];
|
||||
lastMessage.extra = structuredClone(lastMessage.swipe_info?.[newSwipeId]?.extra ?? lastMessage.extra ?? {});
|
||||
}
|
||||
|
||||
await saveChatConditional();
|
||||
|
Reference in New Issue
Block a user