mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'staging' into reasoning-parsing-streaming
This commit is contained in:
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@ -80,6 +80,8 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
- label: I have checked the [docs](https://docs.sillytavern.app/) 
|
- label: I have checked the [docs](https://docs.sillytavern.app/) 
|
||||||
required: true
|
required: true
|
||||||
|
- label: I confirm that my issue is not related to third-party content, unofficial extension or patch. If in doubt, check with a new [user account](https://docs.sillytavern.app/administration/multi-user/) and with extensions disabled
|
||||||
|
required: true
|
||||||
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
@ -210,3 +210,5 @@ claude:
|
|||||||
cachingAtDepth: -1
|
cachingAtDepth: -1
|
||||||
# -- SERVER PLUGIN CONFIGURATION --
|
# -- SERVER PLUGIN CONFIGURATION --
|
||||||
enableServerPlugins: false
|
enableServerPlugins: false
|
||||||
|
# Attempt to automatically update server plugins on startup
|
||||||
|
enableServerPluginsAutoUpdate: true
|
||||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.12.11",
|
"version": "1.12.12",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.12.11",
|
"version": "1.12.12",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
||||||
},
|
},
|
||||||
"version": "1.12.11",
|
"version": "1.12.12",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"debug": "node server.js --inspect",
|
"debug": "node server.js --inspect",
|
||||||
|
@ -48,6 +48,13 @@ async function updatePlugins() {
|
|||||||
console.log(`Updating plugin ${color.green(directory)}...`);
|
console.log(`Updating plugin ${color.green(directory)}...`);
|
||||||
const pluginPath = path.join(pluginsPath, directory);
|
const pluginPath = path.join(pluginsPath, directory);
|
||||||
const pluginRepo = git(pluginPath);
|
const pluginRepo = git(pluginPath);
|
||||||
|
|
||||||
|
const isRepo = await pluginRepo.checkIsRepo();
|
||||||
|
if (!isRepo) {
|
||||||
|
console.log(`Directory ${color.yellow(directory)} is not a Git repository`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
await pluginRepo.fetch();
|
await pluginRepo.fetch();
|
||||||
const commitHash = await pluginRepo.revparse(['HEAD']);
|
const commitHash = await pluginRepo.revparse(['HEAD']);
|
||||||
const trackingBranch = await pluginRepo.revparse(['--abbrev-ref', '@{u}']);
|
const trackingBranch = await pluginRepo.revparse(['--abbrev-ref', '@{u}']);
|
||||||
|
@ -5931,6 +5931,7 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes,
|
|||||||
chat[chat.length - 1]['extra']['api'] = getGeneratingApi();
|
chat[chat.length - 1]['extra']['api'] = getGeneratingApi();
|
||||||
chat[chat.length - 1]['extra']['model'] = getGeneratingModel();
|
chat[chat.length - 1]['extra']['model'] = getGeneratingModel();
|
||||||
chat[chat.length - 1]['extra']['reasoning'] = reasoning;
|
chat[chat.length - 1]['extra']['reasoning'] = reasoning;
|
||||||
|
chat[chat.length - 1]['extra']['reasoning_duration'] = null;
|
||||||
if (power_user.message_token_count_enabled) {
|
if (power_user.message_token_count_enabled) {
|
||||||
const tokenCountText = (reasoning || '') + chat[chat.length - 1]['mes'];
|
const tokenCountText = (reasoning || '') + chat[chat.length - 1]['mes'];
|
||||||
chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(tokenCountText, 0);
|
chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(tokenCountText, 0);
|
||||||
@ -5953,6 +5954,7 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes,
|
|||||||
chat[chat.length - 1]['extra']['api'] = getGeneratingApi();
|
chat[chat.length - 1]['extra']['api'] = getGeneratingApi();
|
||||||
chat[chat.length - 1]['extra']['model'] = getGeneratingModel();
|
chat[chat.length - 1]['extra']['model'] = getGeneratingModel();
|
||||||
chat[chat.length - 1]['extra']['reasoning'] = reasoning;
|
chat[chat.length - 1]['extra']['reasoning'] = reasoning;
|
||||||
|
chat[chat.length - 1]['extra']['reasoning_duration'] = null;
|
||||||
if (power_user.message_token_count_enabled) {
|
if (power_user.message_token_count_enabled) {
|
||||||
const tokenCountText = (reasoning || '') + chat[chat.length - 1]['mes'];
|
const tokenCountText = (reasoning || '') + chat[chat.length - 1]['mes'];
|
||||||
chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(tokenCountText, 0);
|
chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(tokenCountText, 0);
|
||||||
@ -5972,6 +5974,7 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes,
|
|||||||
chat[chat.length - 1]['extra']['api'] = getGeneratingApi();
|
chat[chat.length - 1]['extra']['api'] = getGeneratingApi();
|
||||||
chat[chat.length - 1]['extra']['model'] = getGeneratingModel();
|
chat[chat.length - 1]['extra']['model'] = getGeneratingModel();
|
||||||
chat[chat.length - 1]['extra']['reasoning'] += reasoning;
|
chat[chat.length - 1]['extra']['reasoning'] += reasoning;
|
||||||
|
// We don't know if the reasoning duration extended, so we don't update it here on purpose.
|
||||||
if (power_user.message_token_count_enabled) {
|
if (power_user.message_token_count_enabled) {
|
||||||
const tokenCountText = (reasoning || '') + chat[chat.length - 1]['mes'];
|
const tokenCountText = (reasoning || '') + chat[chat.length - 1]['mes'];
|
||||||
chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(tokenCountText, 0);
|
chat[chat.length - 1]['extra']['token_count'] = await getTokenCountAsync(tokenCountText, 0);
|
||||||
@ -5991,6 +5994,7 @@ export async function saveReply(type, getMessage, fromStreaming, title, swipes,
|
|||||||
chat[chat.length - 1]['extra']['api'] = getGeneratingApi();
|
chat[chat.length - 1]['extra']['api'] = getGeneratingApi();
|
||||||
chat[chat.length - 1]['extra']['model'] = getGeneratingModel();
|
chat[chat.length - 1]['extra']['model'] = getGeneratingModel();
|
||||||
chat[chat.length - 1]['extra']['reasoning'] = reasoning;
|
chat[chat.length - 1]['extra']['reasoning'] = reasoning;
|
||||||
|
chat[chat.length - 1]['extra']['reasoning_duration'] = null;
|
||||||
if (power_user.trim_spaces) {
|
if (power_user.trim_spaces) {
|
||||||
getMessage = getMessage.trim();
|
getMessage = getMessage.trim();
|
||||||
}
|
}
|
||||||
|
@ -346,7 +346,7 @@ export class SettingsUi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async addQrSet() {
|
async addQrSet() {
|
||||||
const name = await Popup.show.input('Create a new World Info', 'Enter a name for the new Quick Reply Set:');
|
const name = await Popup.show.input('Create a new Quick Reply Set', 'Enter a name for the new Quick Reply Set:');
|
||||||
if (name && name.length > 0) {
|
if (name && name.length > 0) {
|
||||||
const oldQrs = QuickReplySet.get(name);
|
const oldQrs = QuickReplySet.get(name);
|
||||||
if (oldQrs) {
|
if (oldQrs) {
|
||||||
|
@ -106,7 +106,7 @@ export function isHiddenReasoningModel() {
|
|||||||
{ name: 'gemini-2.0-pro-exp', func: FUNCS.startsWith },
|
{ name: 'gemini-2.0-pro-exp', func: FUNCS.startsWith },
|
||||||
];
|
];
|
||||||
|
|
||||||
const model = getChatCompletionModel();
|
const model = getChatCompletionModel() || '';
|
||||||
|
|
||||||
const isHidden = hiddenReasoningModels.some(({ name, func }) => func(model, name));
|
const isHidden = hiddenReasoningModels.some(({ name, func }) => func(model, name));
|
||||||
return isHidden;
|
return isHidden;
|
||||||
|
@ -58,9 +58,14 @@ const OPENROUTER_PROVIDERS = [
|
|||||||
'Minimax',
|
'Minimax',
|
||||||
'Nineteen',
|
'Nineteen',
|
||||||
'Liquid',
|
'Liquid',
|
||||||
|
'InferenceNet',
|
||||||
|
'Friendli',
|
||||||
|
'AionLabs',
|
||||||
|
'Alibaba',
|
||||||
'Nebius',
|
'Nebius',
|
||||||
'Chutes',
|
'Chutes',
|
||||||
'Kluster',
|
'Kluster',
|
||||||
|
'Targon',
|
||||||
'01.AI',
|
'01.AI',
|
||||||
'HuggingFace',
|
'HuggingFace',
|
||||||
'Mancer',
|
'Mancer',
|
||||||
|
@ -1275,7 +1275,8 @@ falai.post('/generate', jsonParser, async (request, response) => {
|
|||||||
num_inference_steps: request.body.steps,
|
num_inference_steps: request.body.steps,
|
||||||
seed: request.body.seed ?? null,
|
seed: request.body.seed ?? null,
|
||||||
guidance_scale: request.body.guidance,
|
guidance_scale: request.body.guidance,
|
||||||
enable_safety_checker: false,
|
enable_safety_checker: false, // Disable general safety checks
|
||||||
|
safety_tolerance: 6 // Make Flux the least strict
|
||||||
};
|
};
|
||||||
|
|
||||||
console.debug('FAL.AI request:', requestBody);
|
console.debug('FAL.AI request:', requestBody);
|
||||||
|
@ -3,8 +3,12 @@ import path from 'node:path';
|
|||||||
import url from 'node:url';
|
import url from 'node:url';
|
||||||
|
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import { getConfigValue } from './util.js';
|
import { default as git } from 'simple-git';
|
||||||
const enableServerPlugins = getConfigValue('enableServerPlugins', false);
|
import { sync as commandExistsSync } from 'command-exists';
|
||||||
|
import { getConfigValue, color } from './util.js';
|
||||||
|
|
||||||
|
const enableServerPlugins = !!getConfigValue('enableServerPlugins', false);
|
||||||
|
const enableServerPluginsAutoUpdate = !!getConfigValue('enableServerPluginsAutoUpdate', true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of loaded plugins.
|
* Map of loaded plugins.
|
||||||
@ -54,6 +58,8 @@ export async function loadPlugins(app, pluginsPath) {
|
|||||||
return emptyFn;
|
return emptyFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await updatePlugins(pluginsPath);
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const pluginFilePath = path.join(pluginsPath, file);
|
const pluginFilePath = path.join(pluginsPath, file);
|
||||||
|
|
||||||
@ -70,6 +76,10 @@ export async function loadPlugins(app, pluginsPath) {
|
|||||||
await loadFromFile(app, pluginFilePath, exitHooks);
|
await loadFromFile(app, pluginFilePath, exitHooks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loadedPlugins.size > 0) {
|
||||||
|
console.log(`${loadedPlugins.size} server plugin(s) are currently loaded. Make sure you know exactly what they do, and only install plugins from trusted sources!`);
|
||||||
|
}
|
||||||
|
|
||||||
// Call all plugin "exit" functions at once and wait for them to finish
|
// Call all plugin "exit" functions at once and wait for them to finish
|
||||||
return () => Promise.all(exitHooks.map(exitFn => exitFn()));
|
return () => Promise.all(exitHooks.map(exitFn => exitFn()));
|
||||||
}
|
}
|
||||||
@ -214,3 +224,65 @@ async function initPlugin(app, plugin, exitHooks) {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically update all git plugins in the ./plugins directory
|
||||||
|
* @param {string} pluginsPath Path to plugins directory
|
||||||
|
*/
|
||||||
|
async function updatePlugins(pluginsPath) {
|
||||||
|
if (!enableServerPluginsAutoUpdate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const directories = fs.readdirSync(pluginsPath)
|
||||||
|
.filter(file => !file.startsWith('.'))
|
||||||
|
.filter(file => fs.statSync(path.join(pluginsPath, file)).isDirectory());
|
||||||
|
|
||||||
|
if (directories.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(color.blue('Auto-updating server plugins... Set'), color.yellow('enableServerPluginsAutoUpdate: false'), color.blue('in config.yaml to disable this feature.'));
|
||||||
|
|
||||||
|
if (!commandExistsSync('git')) {
|
||||||
|
console.error(color.red('Git is not installed. Please install Git to enable auto-updating of server plugins.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pluginsToUpdate = 0;
|
||||||
|
|
||||||
|
for (const directory of directories) {
|
||||||
|
try {
|
||||||
|
const pluginPath = path.join(pluginsPath, directory);
|
||||||
|
const pluginRepo = git(pluginPath);
|
||||||
|
|
||||||
|
const isRepo = await pluginRepo.checkIsRepo();
|
||||||
|
if (!isRepo) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await pluginRepo.fetch();
|
||||||
|
const commitHash = await pluginRepo.revparse(['HEAD']);
|
||||||
|
const trackingBranch = await pluginRepo.revparse(['--abbrev-ref', '@{u}']);
|
||||||
|
const log = await pluginRepo.log({
|
||||||
|
from: commitHash,
|
||||||
|
to: trackingBranch,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (log.total === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginsToUpdate++;
|
||||||
|
await pluginRepo.pull();
|
||||||
|
const latestCommit = await pluginRepo.revparse(['HEAD']);
|
||||||
|
console.log(`Plugin ${color.green(directory)} updated to commit ${color.cyan(latestCommit)}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(color.red(`Failed to update plugin ${directory}: ${error.message}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pluginsToUpdate === 0) {
|
||||||
|
console.log('All plugins are up to date.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user