Merge branch 'SillyTavern:staging' into staging
This commit is contained in:
commit
479923051b
|
@ -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=)?**
|
||||
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]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Generation API [e.g. KoboldAI, OpenAI]
|
||||
- Branch [main, dev]
|
||||
- Branch [staging, release]
|
||||
- Model [e.g. Pygmalion 6b, LLaMa 13b]
|
||||
|
||||
**Additional context**
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "sillytavern",
|
||||
"version": "1.9.4",
|
||||
"version": "1.9.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "sillytavern",
|
||||
"version": "1.9.4",
|
||||
"version": "1.9.6",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@dqbd/tiktoken": "^1.0.2",
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
"type": "git",
|
||||
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
||||
},
|
||||
"version": "1.9.4",
|
||||
"version": "1.9.6",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"start-multi": "node server.js --disableCsrf",
|
||||
|
|
|
@ -3681,7 +3681,7 @@
|
|||
</div>
|
||||
|
||||
<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">
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -136,6 +136,7 @@ import {
|
|||
download,
|
||||
isDataURL,
|
||||
getCharaFilename,
|
||||
isDigitsOnly,
|
||||
} from "./scripts/utils.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
|
||||
let is_colab = false;
|
||||
let is_checked_colab = false;
|
||||
let is_mes_reload_avatar = false;
|
||||
let optionsPopper = Popper.createPopper(document.getElementById('options_button'), document.getElementById('options'), {
|
||||
placement: 'top-start'
|
||||
});
|
||||
|
@ -1440,9 +1440,6 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true
|
|||
} else {
|
||||
if (characters[this_chid].avatar != "none") {
|
||||
avatarImg = getThumbnailUrl('avatar', characters[this_chid].avatar);
|
||||
if (is_mes_reload_avatar !== false) {
|
||||
avatarImg += "&" + is_mes_reload_avatar;
|
||||
}
|
||||
} else {
|
||||
avatarImg = default_avatar;
|
||||
}
|
||||
|
@ -1690,7 +1687,7 @@ function getTimeSinceLastMessage() {
|
|||
}
|
||||
|
||||
function randomReplace(input, emptyListPlaceholder = '') {
|
||||
const randomPattern = /{{random:([^}]+)}}/gi;
|
||||
const randomPattern = /{{random[ : ]([^}]+)}}/gi;
|
||||
|
||||
return input.replace(randomPattern, (match, listString) => {
|
||||
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 = '') {
|
||||
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);
|
||||
|
||||
if (!isValid) {
|
||||
|
@ -1848,7 +1850,7 @@ export function extractMessageBias(message) {
|
|||
const match = curMatch[1].trim();
|
||||
|
||||
// Ignore random/roll pattern matches
|
||||
if (/^random:.+/i.test(match) || /^roll:.+/i.test(match)) {
|
||||
if (/^random[ : ].+/i.test(match) || /^roll[ : ].+/i.test(match)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2956,7 +2958,8 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||
}
|
||||
|
||||
//Formating
|
||||
getMessage = cleanUpMessage(getMessage, isImpersonate, isContinue);
|
||||
const displayIncomplete = type == 'quiet';
|
||||
getMessage = cleanUpMessage(getMessage, isImpersonate, isContinue, displayIncomplete);
|
||||
|
||||
let this_mes_is_name;
|
||||
({ this_mes_is_name, getMessage } = extractNameFromMessage(getMessage, force_name2, isImpersonate));
|
||||
|
@ -4268,9 +4271,18 @@ async function read_avatar_load(input) {
|
|||
return;
|
||||
}
|
||||
|
||||
$("#create_button").trigger('click');
|
||||
await createOrEditCharacter();
|
||||
await delay(durationSaveEdit);
|
||||
|
||||
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 () {
|
||||
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');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7574,7 +7576,6 @@ $(document).ready(function () {
|
|||
});
|
||||
|
||||
$("#add_avatar_button").change(function () {
|
||||
is_mes_reload_avatar = Date.now();
|
||||
read_avatar_load(this);
|
||||
});
|
||||
|
||||
|
@ -7780,9 +7781,9 @@ $(document).ready(function () {
|
|||
$("#api_button_textgenerationwebui").click(async function (e) {
|
||||
e.stopPropagation();
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -380,6 +380,7 @@ export async function favsToHotswap() {
|
|||
thisHotSwapSlot.attr('grid', isGroup ? grid : '');
|
||||
thisHotSwapSlot.attr('chid', isCharacter ? chid : '');
|
||||
thisHotSwapSlot.data('id', isGroup ? grid : chid);
|
||||
thisHotSwapSlot.attr('title', '');
|
||||
|
||||
if (isGroup) {
|
||||
const group = groups.find(x => x.id === grid);
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
align-self: center;
|
||||
}
|
||||
|
||||
#rm_print_characters_block .wide100pLess70px {
|
||||
#rm_print_characters_block.bulk_select .wide100pLess70px {
|
||||
width: calc(100% - 85px);
|
||||
}
|
||||
|
|
|
@ -99,12 +99,18 @@ function selectPreset(name) {
|
|||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
function formatTextGenURL(value) {
|
||||
function formatTextGenURL(value, use_mancer) {
|
||||
try {
|
||||
const url = new URL(value);
|
||||
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';
|
||||
}
|
||||
}
|
||||
return url.toString();
|
||||
} catch { } // Just using URL as a validation check
|
||||
return null;
|
||||
|
|
|
@ -4,6 +4,10 @@ export function onlyUnique(value, index, array) {
|
|||
return array.indexOf(value) === index;
|
||||
}
|
||||
|
||||
export function isDigitsOnly(str) {
|
||||
return /^\d+$/.test(str);
|
||||
}
|
||||
|
||||
export function shuffle(array) {
|
||||
let currentIndex = array.length,
|
||||
randomIndex;
|
||||
|
|
|
@ -954,10 +954,6 @@ select {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#rm_ch_create_block textarea {
|
||||
min-height: 190px;
|
||||
}
|
||||
|
||||
.margin-bot-10px,
|
||||
.marginBot10 {
|
||||
margin-bottom: 10px;
|
||||
|
@ -1724,11 +1720,14 @@ body.big-avatars .ch_description {
|
|||
|
||||
|
||||
#form_create {
|
||||
display: grid;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
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 {
|
||||
|
@ -1759,7 +1758,6 @@ body.big-avatars #avatar_div_div.avatar img {
|
|||
#avatar-and-name-block {
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
flex: 0 0 100%;
|
||||
flex-wrap: wrap;
|
||||
/* margin-bottom: 4px; */
|
||||
}
|
||||
|
@ -5108,11 +5106,6 @@ body.waifuMode .zoomed_avatar {
|
|||
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 {
|
||||
font-size: calc(var(--mainFontSize) - .1rem);
|
||||
}
|
||||
|
@ -5128,10 +5121,6 @@ body.waifuMode .zoomed_avatar {
|
|||
height: calc(100% - 40px);
|
||||
}
|
||||
|
||||
#rm_ch_create_block textarea {
|
||||
max-height: 190px;
|
||||
}
|
||||
|
||||
.drawer25pWidth {
|
||||
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);
|
||||
}, timeout);
|
||||
} 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) {
|
||||
console.error('Error:', error.message);
|
||||
function handleError(error, response_generate_openai, errorData) {
|
||||
console.error('Error:', error?.message);
|
||||
|
||||
let message = error?.response?.statusText;
|
||||
|
||||
switch (error?.response?.status) {
|
||||
case 402:
|
||||
message = error?.response?.data?.error?.message || 'Credit limit reached';
|
||||
const statusMessages = {
|
||||
400: 'Bad request',
|
||||
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);
|
||||
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 }
|
||||
if (!response_generate_openai.headersSent) {
|
||||
response_generate_openai.send(response);
|
||||
|
|
Loading…
Reference in New Issue