mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-03-03 03:17:54 +01:00
Merge branch 'SillyTavern:staging' into staging
This commit is contained in:
commit
479923051b
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -7,7 +7,7 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
> **Warning**. Complete **all** the fields below. Otherwise your bug report will be **ignored**!
|
> **Warning**. Complete **all** the fields below. Otherwise, your bug report will be **ignored**!
|
||||||
|
|
||||||
**Have you searched for similar [bugs](https://github.com/SillyTavern/SillyTavern/issues?q=)?**
|
**Have you searched for similar [bugs](https://github.com/SillyTavern/SillyTavern/issues?q=)?**
|
||||||
Yes/No
|
Yes/No
|
||||||
@ -38,7 +38,7 @@ Providing the logs from the browser DevTools console (opened by pressing the F12
|
|||||||
- Node.js version (if applicable): [run `node --version` in cmd]
|
- Node.js version (if applicable): [run `node --version` in cmd]
|
||||||
- Browser [e.g. chrome, safari]
|
- Browser [e.g. chrome, safari]
|
||||||
- Generation API [e.g. KoboldAI, OpenAI]
|
- Generation API [e.g. KoboldAI, OpenAI]
|
||||||
- Branch [main, dev]
|
- Branch [staging, release]
|
||||||
- Model [e.g. Pygmalion 6b, LLaMa 13b]
|
- Model [e.g. Pygmalion 6b, LLaMa 13b]
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.9.4",
|
"version": "1.9.6",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.9.4",
|
"version": "1.9.6",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dqbd/tiktoken": "^1.0.2",
|
"@dqbd/tiktoken": "^1.0.2",
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
||||||
},
|
},
|
||||||
"version": "1.9.4",
|
"version": "1.9.6",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"start-multi": "node server.js --disableCsrf",
|
"start-multi": "node server.js --disableCsrf",
|
||||||
|
@ -3681,7 +3681,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="hotswap_template" class="template_element">
|
<div id="hotswap_template" class="template_element">
|
||||||
<div class="hotswapAvatar">
|
<div class="hotswapAvatar" title="Add a character/group to favorites to display it here!">
|
||||||
<img src="/img/ai4.png">
|
<img src="/img/ai4.png">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -136,6 +136,7 @@ import {
|
|||||||
download,
|
download,
|
||||||
isDataURL,
|
isDataURL,
|
||||||
getCharaFilename,
|
getCharaFilename,
|
||||||
|
isDigitsOnly,
|
||||||
} from "./scripts/utils.js";
|
} from "./scripts/utils.js";
|
||||||
|
|
||||||
import { extension_settings, getContext, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from "./scripts/extensions.js";
|
import { extension_settings, getContext, loadExtensionSettings, runGenerationInterceptors, saveMetadataDebounced } from "./scripts/extensions.js";
|
||||||
@ -304,7 +305,6 @@ export const comment_avatar = "img/quill.png";
|
|||||||
export let CLIENT_VERSION = 'SillyTavern:UNKNOWN:Cohee#1207'; // For Horde header
|
export let CLIENT_VERSION = 'SillyTavern:UNKNOWN:Cohee#1207'; // For Horde header
|
||||||
let is_colab = false;
|
let is_colab = false;
|
||||||
let is_checked_colab = false;
|
let is_checked_colab = false;
|
||||||
let is_mes_reload_avatar = false;
|
|
||||||
let optionsPopper = Popper.createPopper(document.getElementById('options_button'), document.getElementById('options'), {
|
let optionsPopper = Popper.createPopper(document.getElementById('options_button'), document.getElementById('options'), {
|
||||||
placement: 'top-start'
|
placement: 'top-start'
|
||||||
});
|
});
|
||||||
@ -1440,9 +1440,6 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true
|
|||||||
} else {
|
} else {
|
||||||
if (characters[this_chid].avatar != "none") {
|
if (characters[this_chid].avatar != "none") {
|
||||||
avatarImg = getThumbnailUrl('avatar', characters[this_chid].avatar);
|
avatarImg = getThumbnailUrl('avatar', characters[this_chid].avatar);
|
||||||
if (is_mes_reload_avatar !== false) {
|
|
||||||
avatarImg += "&" + is_mes_reload_avatar;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
avatarImg = default_avatar;
|
avatarImg = default_avatar;
|
||||||
}
|
}
|
||||||
@ -1690,7 +1687,7 @@ function getTimeSinceLastMessage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function randomReplace(input, emptyListPlaceholder = '') {
|
function randomReplace(input, emptyListPlaceholder = '') {
|
||||||
const randomPattern = /{{random:([^}]+)}}/gi;
|
const randomPattern = /{{random[ : ]([^}]+)}}/gi;
|
||||||
|
|
||||||
return input.replace(randomPattern, (match, listString) => {
|
return input.replace(randomPattern, (match, listString) => {
|
||||||
const list = listString.split(',').map(item => item.trim()).filter(item => item.length > 0);
|
const list = listString.split(',').map(item => item.trim()).filter(item => item.length > 0);
|
||||||
@ -1708,10 +1705,15 @@ function randomReplace(input, emptyListPlaceholder = '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function diceRollReplace(input, invalidRollPlaceholder = '') {
|
function diceRollReplace(input, invalidRollPlaceholder = '') {
|
||||||
const randomPattern = /{{roll:([^}]+)}}/gi;
|
const rollPattern = /{{roll[ : ]([^}]+)}}/gi;
|
||||||
|
|
||||||
|
return input.replace(rollPattern, (match, matchValue) => {
|
||||||
|
let formula = matchValue.trim();
|
||||||
|
|
||||||
|
if (isDigitsOnly(formula)) {
|
||||||
|
formula = `1d${formula}`;
|
||||||
|
}
|
||||||
|
|
||||||
return input.replace(randomPattern, (match, matchValue) => {
|
|
||||||
const formula = matchValue.trim();
|
|
||||||
const isValid = droll.validate(formula);
|
const isValid = droll.validate(formula);
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
@ -1848,7 +1850,7 @@ export function extractMessageBias(message) {
|
|||||||
const match = curMatch[1].trim();
|
const match = curMatch[1].trim();
|
||||||
|
|
||||||
// Ignore random/roll pattern matches
|
// Ignore random/roll pattern matches
|
||||||
if (/^random:.+/i.test(match) || /^roll:.+/i.test(match)) {
|
if (/^random[ : ].+/i.test(match) || /^roll[ : ].+/i.test(match)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2956,7 +2958,8 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Formating
|
//Formating
|
||||||
getMessage = cleanUpMessage(getMessage, isImpersonate, isContinue);
|
const displayIncomplete = type == 'quiet';
|
||||||
|
getMessage = cleanUpMessage(getMessage, isImpersonate, isContinue, displayIncomplete);
|
||||||
|
|
||||||
let this_mes_is_name;
|
let this_mes_is_name;
|
||||||
({ this_mes_is_name, getMessage } = extractNameFromMessage(getMessage, force_name2, isImpersonate));
|
({ this_mes_is_name, getMessage } = extractNameFromMessage(getMessage, force_name2, isImpersonate));
|
||||||
@ -4268,9 +4271,18 @@ async function read_avatar_load(input) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#create_button").trigger('click');
|
await createOrEditCharacter();
|
||||||
|
await delay(durationSaveEdit);
|
||||||
|
|
||||||
const formData = new FormData($("#form_create").get(0));
|
const formData = new FormData($("#form_create").get(0));
|
||||||
|
await fetch(getThumbnailUrl('avatar', formData.get('avatar_url')), {
|
||||||
|
method: 'GET',
|
||||||
|
cache: 'no-cache',
|
||||||
|
headers: {
|
||||||
|
'pragma': 'no-cache',
|
||||||
|
'cache-control': 'no-cache',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$(".mes").each(async function () {
|
$(".mes").each(async function () {
|
||||||
if ($(this).attr("is_system") == 'true') {
|
if ($(this).attr("is_system") == 'true') {
|
||||||
@ -4288,17 +4300,7 @@ async function read_avatar_load(input) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await delay(durationSaveEdit);
|
|
||||||
await fetch(getThumbnailUrl('avatar', formData.get('avatar_url')), {
|
|
||||||
method: 'GET',
|
|
||||||
cache: 'no-cache',
|
|
||||||
headers: {
|
|
||||||
'pragma': 'no-cache',
|
|
||||||
'cache-control': 'no-cache',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
console.log('Avatar refreshed');
|
console.log('Avatar refreshed');
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7574,7 +7576,6 @@ $(document).ready(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$("#add_avatar_button").change(function () {
|
$("#add_avatar_button").change(function () {
|
||||||
is_mes_reload_avatar = Date.now();
|
|
||||||
read_avatar_load(this);
|
read_avatar_load(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -7780,9 +7781,9 @@ $(document).ready(function () {
|
|||||||
$("#api_button_textgenerationwebui").click(async function (e) {
|
$("#api_button_textgenerationwebui").click(async function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if ($("#textgenerationwebui_api_url_text").val() != "") {
|
if ($("#textgenerationwebui_api_url_text").val() != "") {
|
||||||
let value = formatTextGenURL($("#textgenerationwebui_api_url_text").val().trim())
|
let value = formatTextGenURL($("#textgenerationwebui_api_url_text").val().trim(), api_use_mancer_webui);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
callPopup('Please enter a valid URL.<br/>WebUI URLs should end with <tt>/api</tt>', 'text');
|
callPopup("Please enter a valid URL.<br/>WebUI URLs should end with <tt>/api</tt><br/>Enable 'Relaxed API URLs' to allow other paths.", 'text');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,6 +380,7 @@ export async function favsToHotswap() {
|
|||||||
thisHotSwapSlot.attr('grid', isGroup ? grid : '');
|
thisHotSwapSlot.attr('grid', isGroup ? grid : '');
|
||||||
thisHotSwapSlot.attr('chid', isCharacter ? chid : '');
|
thisHotSwapSlot.attr('chid', isCharacter ? chid : '');
|
||||||
thisHotSwapSlot.data('id', isGroup ? grid : chid);
|
thisHotSwapSlot.data('id', isGroup ? grid : chid);
|
||||||
|
thisHotSwapSlot.attr('title', '');
|
||||||
|
|
||||||
if (isGroup) {
|
if (isGroup) {
|
||||||
const group = groups.find(x => x.id === grid);
|
const group = groups.find(x => x.id === grid);
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#rm_print_characters_block .wide100pLess70px {
|
#rm_print_characters_block.bulk_select .wide100pLess70px {
|
||||||
width: calc(100% - 85px);
|
width: calc(100% - 85px);
|
||||||
}
|
}
|
||||||
|
@ -99,12 +99,18 @@ function selectPreset(name) {
|
|||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatTextGenURL(value) {
|
function formatTextGenURL(value, use_mancer) {
|
||||||
try {
|
try {
|
||||||
const url = new URL(value);
|
const url = new URL(value);
|
||||||
if (!power_user.relaxed_api_urls) {
|
if (!power_user.relaxed_api_urls) {
|
||||||
|
if (use_mancer) { // If Mancer is in use, only require the URL to *end* with `/api`.
|
||||||
|
if (!url.pathname.endsWith('/api')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
url.pathname = '/api';
|
url.pathname = '/api';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return url.toString();
|
return url.toString();
|
||||||
} catch { } // Just using URL as a validation check
|
} catch { } // Just using URL as a validation check
|
||||||
return null;
|
return null;
|
||||||
|
@ -4,6 +4,10 @@ export function onlyUnique(value, index, array) {
|
|||||||
return array.indexOf(value) === index;
|
return array.indexOf(value) === index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isDigitsOnly(str) {
|
||||||
|
return /^\d+$/.test(str);
|
||||||
|
}
|
||||||
|
|
||||||
export function shuffle(array) {
|
export function shuffle(array) {
|
||||||
let currentIndex = array.length,
|
let currentIndex = array.length,
|
||||||
randomIndex;
|
randomIndex;
|
||||||
|
@ -954,10 +954,6 @@ select {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
#rm_ch_create_block textarea {
|
|
||||||
min-height: 190px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.margin-bot-10px,
|
.margin-bot-10px,
|
||||||
.marginBot10 {
|
.marginBot10 {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
@ -1724,11 +1720,14 @@ body.big-avatars .ch_description {
|
|||||||
|
|
||||||
|
|
||||||
#form_create {
|
#form_create {
|
||||||
display: grid;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
grid-template-rows:
|
}
|
||||||
[avatar] min-content [hr] min-content [descriptionHeader] min-content [description] auto [firstmessageHeader] min-content [firstMessage] auto [hidden] min-content;
|
|
||||||
|
#form_create textarea {
|
||||||
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar_div {
|
.avatar_div {
|
||||||
@ -1759,7 +1758,6 @@ body.big-avatars #avatar_div_div.avatar img {
|
|||||||
#avatar-and-name-block {
|
#avatar-and-name-block {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 100%;
|
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
/* margin-bottom: 4px; */
|
/* margin-bottom: 4px; */
|
||||||
}
|
}
|
||||||
@ -5108,11 +5106,6 @@ body.waifuMode .zoomed_avatar {
|
|||||||
margin: 5px auto;
|
margin: 5px auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#form_create {
|
|
||||||
grid-template-rows:
|
|
||||||
[avatar] min-content [hr] min-content [descriptionHeader] min-content [description] auto [firstmessageHeader] min-content [firstMessage] auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#result_info {
|
#result_info {
|
||||||
font-size: calc(var(--mainFontSize) - .1rem);
|
font-size: calc(var(--mainFontSize) - .1rem);
|
||||||
}
|
}
|
||||||
@ -5128,10 +5121,6 @@ body.waifuMode .zoomed_avatar {
|
|||||||
height: calc(100% - 40px);
|
height: calc(100% - 40px);
|
||||||
}
|
}
|
||||||
|
|
||||||
#rm_ch_create_block textarea {
|
|
||||||
max-height: 190px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer25pWidth {
|
.drawer25pWidth {
|
||||||
flex-basis: max(calc(100% / 4 - 10px), 190px);
|
flex-basis: max(calc(100% / 4 - 10px), 190px);
|
||||||
}
|
}
|
||||||
|
48
server.js
48
server.js
@ -3327,7 +3327,22 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
|||||||
makeRequest(config, response_generate_openai, request, retries - 1);
|
makeRequest(config, response_generate_openai, request, retries - 1);
|
||||||
}, timeout);
|
}, timeout);
|
||||||
} else {
|
} else {
|
||||||
handleError(error, response_generate_openai, request);
|
let errorData = error?.response?.data;
|
||||||
|
|
||||||
|
if (request.body.stream) {
|
||||||
|
try {
|
||||||
|
const chunks = await readAllChunks(errorData);
|
||||||
|
const blob = new Blob(chunks, { type: 'application/json' });
|
||||||
|
const text = await blob.text();
|
||||||
|
errorData = JSON.parse(text);
|
||||||
|
} catch {
|
||||||
|
console.warn('Error parsing streaming response');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errorData = typeof errorData === 'string' ? tryParse(errorData) : errorData;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleError(error, response_generate_openai, errorData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3339,27 +3354,28 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleError(error, response_generate_openai, request) {
|
function handleError(error, response_generate_openai, errorData) {
|
||||||
console.error('Error:', error.message);
|
console.error('Error:', error?.message);
|
||||||
|
|
||||||
let message = error?.response?.statusText;
|
let message = error?.response?.statusText;
|
||||||
|
|
||||||
switch (error?.response?.status) {
|
const statusMessages = {
|
||||||
case 402:
|
400: 'Bad request',
|
||||||
message = error?.response?.data?.error?.message || 'Credit limit reached';
|
401: 'Unauthorized',
|
||||||
|
402: 'Credit limit reached',
|
||||||
|
403: 'Forbidden',
|
||||||
|
404: 'Not found',
|
||||||
|
429: 'Too many requests',
|
||||||
|
451: 'Unavailable for legal reasons',
|
||||||
|
};
|
||||||
|
|
||||||
|
const status = error?.response?.status;
|
||||||
|
if (statusMessages.hasOwnProperty(status)) {
|
||||||
|
message = errorData?.error?.message || statusMessages[status];
|
||||||
console.log(message);
|
console.log(message);
|
||||||
break;
|
|
||||||
case 403:
|
|
||||||
message = error?.response?.data?.error?.message || 'API key disabled or exhausted';
|
|
||||||
console.log(message);
|
|
||||||
break;
|
|
||||||
case 451:
|
|
||||||
message = error?.response?.data?.error?.message || 'Unavailable for legal reasons';
|
|
||||||
console.log(message);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const quota_error = error?.response?.status === 429 && error?.response?.data?.error?.type === 'insufficient_quota';
|
const quota_error = error?.response?.status === 429 && errorData?.error?.type === 'insufficient_quota';
|
||||||
const response = { error: { message }, quota_error: quota_error }
|
const response = { error: { message }, quota_error: quota_error }
|
||||||
if (!response_generate_openai.headersSent) {
|
if (!response_generate_openai.headersSent) {
|
||||||
response_generate_openai.send(response);
|
response_generate_openai.send(response);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user