Merge remote-tracking branch 'upstream/staging' into staging

This commit is contained in:
DonMoralez 2023-12-24 13:31:21 +02:00
commit 3ac971b145
7 changed files with 55 additions and 8 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "sillytavern",
"version": "1.11.1",
"version": "1.11.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sillytavern",
"version": "1.11.1",
"version": "1.11.2",
"hasInstallScript": true,
"license": "AGPL-3.0",
"dependencies": {

View File

@ -51,7 +51,7 @@
"type": "git",
"url": "https://github.com/SillyTavern/SillyTavern.git"
},
"version": "1.11.1",
"version": "1.11.2",
"scripts": {
"start": "node server.js",
"start-multi": "node server.js --disableCsrf",

View File

@ -2974,9 +2974,11 @@ async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, qu
return Promise.resolve();
}
// Hide swipes if not in a dry run.
if (!dryRun) {
// Hide swipes if not in a dry run.
hideSwipeButtons();
// If generated any message, set the flag to indicate it can't be recreated again.
chat_metadata['tainted'] = true;
}
if (selected_group && !is_group_generating && !dryRun) {
@ -7105,7 +7107,8 @@ async function createOrEditCharacter(e) {
crop_data = undefined;
eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: this_chid, character: characters[this_chid] } });
if (chat.length === 1 && !selected_group) {
// Recreate the chat if it hasn't been used at least once (i.e. with continue).
if (chat.length === 1 && !selected_group && !chat_metadata['tainted']) {
const firstMessage = getFirstMessage();
chat[0] = firstMessage;

View File

@ -286,6 +286,7 @@ jQuery(function () {
(extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'google' && secret_state[SECRET_KEYS.MAKERSUITE]) ||
(extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'ollama' && textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]) ||
(extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'llamacpp' && textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP]) ||
(extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'ooba' && textgenerationwebui_settings.server_urls[textgen_types.OOBA]) ||
(extension_settings.caption.source === 'multimodal' && extension_settings.caption.multimodal_api === 'custom') ||
extension_settings.caption.source === 'local' ||
extension_settings.caption.source === 'horde';
@ -351,6 +352,7 @@ jQuery(function () {
<label for="caption_multimodal_api">API</label>
<select id="caption_multimodal_api" class="flex1 text_pole">
<option value="llamacpp">llama.cpp</option>
<option value="ooba">Text Generation WebUI (oobabooga)</option>
<option value="ollama">Ollama</option>
<option value="openai">OpenAI</option>
<option value="openrouter">OpenRouter</option>
@ -369,6 +371,7 @@ jQuery(function () {
<option data-type="ollama" value="bakllava:latest">bakllava:latest</option>
<option data-type="ollama" value="llava:latest">llava:latest</option>
<option data-type="llamacpp" value="llamacpp_current">[Currently loaded]</option>
<option data-type="ooba" value="ooba_current">[Currently loaded]</option>
<option data-type="custom" value="custom_current">[Currently selected]</option>
</select>
</div>

View File

@ -21,13 +21,15 @@ export async function getMultimodalCaption(base64Img, prompt) {
}
// OpenRouter has a payload limit of ~2MB. Google is 4MB, but we love democracy.
// Ooba requires all images to be JPEGs.
const isGoogle = extension_settings.caption.multimodal_api === 'google';
const isOllama = extension_settings.caption.multimodal_api === 'ollama';
const isLlamaCpp = extension_settings.caption.multimodal_api === 'llamacpp';
const isCustom = extension_settings.caption.multimodal_api === 'custom';
const isOoba = extension_settings.caption.multimodal_api === 'ooba';
const base64Bytes = base64Img.length * 0.75;
const compressionLimit = 2 * 1024 * 1024;
if (['google', 'openrouter'].includes(extension_settings.caption.multimodal_api) && base64Bytes > compressionLimit) {
if ((['google', 'openrouter'].includes(extension_settings.caption.multimodal_api) && base64Bytes > compressionLimit) || isOoba) {
const maxSide = 1024;
base64Img = await createThumbnail(base64Img, maxSide, maxSide, 'image/jpeg');
@ -69,6 +71,10 @@ export async function getMultimodalCaption(base64Img, prompt) {
requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.LLAMACPP];
}
if (isOoba) {
requestBody.server_url = textgenerationwebui_settings.server_urls[textgen_types.OOBA];
}
if (isCustom) {
requestBody.server_url = oai_settings.custom_url;
requestBody.model = oai_settings.custom_model || 'gpt-4-vision-preview';
@ -129,6 +135,10 @@ function throwIfInvalidModel() {
throw new Error('LlamaCPP server URL is not set.');
}
if (extension_settings.caption.multimodal_api === 'ooba' && !textgenerationwebui_settings.server_urls[textgen_types.OOBA]) {
throw new Error('Text Generation WebUI server URL is not set.');
}
if (extension_settings.caption.multimodal_api === 'custom' && !oai_settings.custom_url) {
throw new Error('Custom API URL is not set.');
}

View File

@ -4,7 +4,7 @@ const express = require('express');
const FormData = require('form-data');
const fs = require('fs');
const { jsonParser, urlencodedParser } = require('../express-common');
const { getConfigValue, mergeObjectWithYaml, excludeKeysByYaml } = require('../util');
const { getConfigValue, mergeObjectWithYaml, excludeKeysByYaml, trimV1 } = require('../util');
const router = express.Router();
@ -32,7 +32,11 @@ router.post('/caption-image', jsonParser, async (request, response) => {
mergeObjectWithYaml(headers, request.body.custom_include_headers);
}
if (!key && !request.body.reverse_proxy && request.body.api !== 'custom') {
if (request.body.api === 'ooba') {
bodyParams.temperature = 0.1;
}
if (!key && !request.body.reverse_proxy && request.body.api !== 'custom' && request.body.api !== 'ooba') {
console.log('No key found for API', request.body.api);
return response.sendStatus(400);
}
@ -85,6 +89,20 @@ router.post('/caption-image', jsonParser, async (request, response) => {
apiUrl = `${request.body.server_url}/chat/completions`;
}
if (request.body.api === 'ooba') {
apiUrl = `${trimV1(request.body.server_url)}/v1/chat/completions`;
const imgMessage = body.messages.pop();
body.messages.push({
role: 'user',
content: imgMessage?.content?.[0]?.text,
});
body.messages.push({
role: 'user',
content: [],
image_url: imgMessage?.content?.[1]?.image_url?.url,
});
}
const result = await fetch(apiUrl, {
method: 'POST',
headers: {

View File

@ -5,6 +5,12 @@ const express = require('express');
const { getConfigValue } = require('./util');
const enableServerPlugins = getConfigValue('enableServerPlugins', false);
/**
* Map of loaded plugins.
* @type {Map<string, any>}
*/
const loadedPlugins = new Map();
/**
* Determine if a file is a CommonJS module.
* @param {string} file Path to file
@ -186,11 +192,18 @@ async function initPlugin(app, plugin, exitHooks) {
return false;
}
if (loadedPlugins.has(id)) {
console.error(`Failed to load plugin module; plugin ID '${id}' is already in use`);
return false;
}
// Allow the plugin to register API routes under /api/plugins/[plugin ID] via a router
const router = express.Router();
await plugin.init(router);
loadedPlugins.set(id, plugin);
// Add API routes to the app if the plugin registered any
if (router.stack.length > 0) {
app.use(`/api/plugins/${id}`, router);