Merge branch 'SillyTavern:staging' into staging

This commit is contained in:
pyrater 2023-08-04 06:43:17 +09:00 committed by GitHub
commit f106666ded
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 342 additions and 57 deletions

View File

@ -5,3 +5,4 @@ readme*
Start.bat
/dist
/backups/
cloudflared.exe

1
.gitignore vendored
View File

@ -28,3 +28,4 @@ secrets.json
public/movingUI/
public/QuickReplies/
content.log
cloudflared.exe

18
Remote-Link.cmd Normal file
View File

@ -0,0 +1,18 @@
@echo off
echo ========================================================================================================================
echo WARNING: Cloudflare Tunnel!
echo ========================================================================================================================
echo This script downloads and runs the latest cloudflared.exe from Cloudflare to set up an HTTPS tunnel to your SillyTavern!
echo Using the randomly generated temporary tunnel URL, anyone can access your SillyTavern over the Internet while the tunnel
echo is active. Keep the URL safe and secure your SillyTavern installation by setting a username and password in config.conf!
echo.
echo See https://docs.sillytavern.app/usage/remoteconnections/ for more details about how to secure your SillyTavern install.
echo.
echo By continuing you confirm that you're aware of the potential dangers of having a tunnel open and take all responsibility
echo to properly use and secure it!
echo.
echo To abort, press Ctrl+C or close this window now!
echo.
pause
if not exist cloudflared.exe curl -Lo cloudflared.exe https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe
cloudflared.exe tunnel --url localhost:8000

View File

@ -1555,30 +1555,55 @@
</div>
</div>
<div id="textgenerationwebui_api" style="display: none;position: relative;">
<div class="flex-container">
<a href="https://github.com/oobabooga/text-generation-webui" target="_blank">
oobabooga/text-generation-webui
</a>
<span data-i18n="Make sure you run it with">
Make sure you run it with <tt>--api</tt> flag
</span>
</div>
<div>
<div class="flex-container flexFlowColumn">
<div class="flex1">
<h4 data-i18n="Blocking API url">Blocking API url</h4>
<small>Example: http://127.0.0.1:5000/</small>
<input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
</div>
<div class="flex1">
<h4 data-i18n="Streaming API url">Streaming API url</h4>
<small>Example: ws://127.0.0.1:5005/api/v1/stream</small>
<input id="streaming_url_textgenerationwebui" type="text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
<form action="javascript:void(null);" method="post" enctype="multipart/form-data">
If you are using:
<div class="flex-container indent20p">
<a href="https://github.com/oobabooga/text-generation-webui" target="_blank">
oobabooga/text-generation-webui
</a>,
<span data-i18n="Make sure you run it with">
Make sure you run it with <tt>--api</tt> flag
</span>
</div>
<div class="flex-container indent20p">
<a href="https://mancer.tech/" target="_blank">
Mancer AI
</a>,
<label class="checkbox_label" for="use-mancer-api-checkbox">
<span data-i18n="Use API key (Only required for Mancer)">
Click this box (and add your API key!):
</span>
<input id="use-mancer-api-checkbox" type="checkbox" />
</label>
</div>
<div id="mancer-api-ui" style="display:none;">
<h4 data-i18n="Mancer API key">Mancer API key</h4>
<div class="flex-container">
<input id="api_key_mancer" name="api_key_mancer" class="text_pole flex1 wide100p" maxlength="500" size="35" type="text" autocomplete="off">
<div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_mancer">
</div>
</div>
</div>
<input id="api_button_textgenerationwebui" class="menu_button" type="submit" value="Connect">
<div id="api_loading_textgenerationwebui" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
</div>
<div>
<div class="flex-container flexFlowColumn">
<div data-for="api_key_mancer" class="neutral_warning" data-i18n="For privacy reasons, your API key will be hidden after you reload the page.">
For privacy reasons, your API key will be hidden after you reload the page.
</div>
<div class="flex1">
<h4 data-i18n="Blocking API url">Blocking API url</h4>
<small>Example: http://127.0.0.1:5000/</small>
<input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
</div>
<div class="flex1">
<h4 data-i18n="Streaming API url">Streaming API url</h4>
<small>Example: ws://127.0.0.1:5005/api/v1/stream</small>
<input id="streaming_url_textgenerationwebui" type="text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
</div>
</div>
<input id="api_button_textgenerationwebui" class="menu_button" type="submit" value="Connect">
<div id="api_loading_textgenerationwebui" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
</div>
</form>
<div class="online_status4">
<div class="online_status_indicator4"></div>
<div class="online_status_text4" data-i18n="Not connected">Not connected</div>
@ -2639,6 +2664,14 @@
<option value="3" data-i18n="Bottom of Author's Note">Bottom of Author's Note</option>
</select>
</div>
<div class="range-block">
<label for="persona_show_notifications" class="checkbox_label">
<input id="persona_show_notifications" type="checkbox" />
<span data-i18n="Show Notifications Show notifications on switching personas">
Show notifications on switching personas
</span>
</label>
</div>
</div>
<div class="flex1">
<h4 class="title_restorable">
@ -3276,7 +3309,7 @@
<div title="Rename chat file" class="renameChatButton fa-solid fa-pen" data-i18n="[title]Rename chat file"></div>
<div title="Export JSONL chat file" data-format="jsonl" class="exportRawChatButton fa-solid fa-file-export" data-i18n="[title]Export JSONL chat file"></div>
<div title="Download chat as plain text document" data-format="txt" class="exportChatButton fa-solid fa-file-lines" data-i18n="[title]Download chat as plain text document"></div>
<div title="Delete chat file" file_name="" class="PastChat_cross fa-solid fa-circle-xmark" data-i18n="[title]Delete chat file"></div>
<div title="Delete chat file" file_name="" class="PastChat_cross fa-solid fa-skull" data-i18n="[title]Delete chat file"></div>
</div>
</div>
</div>

View File

@ -17,6 +17,7 @@ import {
loadTextGenSettings,
generateTextGenWithStreaming,
getTextGenGenerationData,
formatTextGenURL,
} from "./scripts/textgen-settings.js";
import {
@ -721,6 +722,7 @@ let is_get_status = false;
let is_get_status_novel = false;
let is_api_button_press = false;
let is_api_button_press_novel = false;
let api_use_mancer_webui = false;
let is_send_press = false; //Send generation
let add_mes_without_animation = false;
@ -854,9 +856,9 @@ async function getStatus() {
type: "POST", //
url: "/getstatus", //
data: JSON.stringify({
api_server:
main_api == "kobold" ? api_server : api_server_textgenerationwebui,
api_server: main_api == "kobold" ? api_server : api_server_textgenerationwebui,
main_api: main_api,
use_mancer: main_api == "textgenerationwebui" ? api_use_mancer_webui : false,
}),
beforeSend: function () { },
cache: false,
@ -883,6 +885,11 @@ async function getStatus() {
kai_settings.can_use_streaming = canUseKoboldStreaming(data.koboldVersion);
}
// We didn't get a 200 status code, but the endpoint has an explanation. Which means it DID connect, but I digress.
if (online_status == "no_connection" && data.response) {
toastr.error(data.response, "API Error", {timeOut: 5000, preventDuplicates:true})
}
//console.log(online_status);
resultCheckStatus();
if (online_status !== "no_connection") {
@ -2716,6 +2723,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
}
else if (main_api == 'textgenerationwebui') {
generate_data = getTextGenGenerationData(finalPromt, this_amount_gen, isImpersonate);
generate_data.use_mancer = api_use_mancer_webui;
}
else if (main_api == 'novel') {
const this_settings = novelai_settings[novelai_setting_names[nai_settings.preset_settings_novel]];
@ -2978,6 +2986,13 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
activateSendButtons();
//console.log('runGenerate calling showSwipeBtns');
showSwipeButtons();
if (main_api == 'textgenerationwebui' && api_use_mancer_webui) {
const errorText = `<h3>Inferencer endpoint is unhappy!</h3>
Returned status <tt>${data.status}</tt> with the reason:<br/>
${data.response}`;
callPopup(errorText, 'text');
}
}
console.debug('/savechat called by /Generate');
@ -4554,7 +4569,9 @@ export function setUserName(value) {
name1 = default_user_name;
console.log(`User name changed to ${name1}`);
$("#your_name").val(name1);
toastr.success(`Your messages will now be sent as ${name1}`, 'Current persona updated');
if (power_user.persona_show_notifications) {
toastr.success(`Your messages will now be sent as ${name1}`, 'Current persona updated');
}
saveSettings("change_name");
}
@ -4653,7 +4670,7 @@ function setUserAvatar() {
const personaName = power_user.personas[user_avatar];
if (personaName && name1 !== personaName) {
const lockedPersona = chat_metadata['persona'];
if (lockedPersona && lockedPersona !== user_avatar) {
if (lockedPersona && lockedPersona !== user_avatar && power_user.persona_show_notifications) {
toastr.info(
`To permanently set "${personaName}" as the selected persona, unlock and relock it using the "Lock" button. Otherwise, the selection resets upon reloading the chat.`,
`This chat is locked to a different persona (${power_user.personas[lockedPersona]}).`,
@ -4760,7 +4777,9 @@ async function setDefaultPersona() {
}
console.log(`Removing default persona ${avatarId}`);
toastr.info('This persona will no longer be used by default when you open a new chat.', `Default persona removed`);
if (power_user.persona_show_notifications) {
toastr.info('This persona will no longer be used by default when you open a new chat.', `Default persona removed`);
}
delete power_user.default_persona;
} else {
const confirm = await callPopup(`<h3>Are you sure you want to set "${personaName}" as the default persona?</h3>
@ -4772,7 +4791,9 @@ async function setDefaultPersona() {
}
power_user.default_persona = avatarId;
toastr.success('This persona will be used by default when you open a new chat.', `Default persona set to ${personaName}`);
if (power_user.persona_show_notifications) {
toastr.success('This persona will be used by default when you open a new chat.', `Default persona set to ${personaName}`);
}
}
saveSettingsDebounced();
@ -4835,18 +4856,22 @@ function lockUserNameToChat() {
console.log(`Unlocking persona for this chat ${chat_metadata['persona']}`);
delete chat_metadata['persona'];
saveMetadata();
toastr.info('User persona is now unlocked for this chat. Click the "Lock" again to revert.', 'Persona unlocked');
if (power_user.persona_show_notifications) {
toastr.info('User persona is now unlocked for this chat. Click the "Lock" again to revert.', 'Persona unlocked');
}
updateUserLockIcon();
return;
}
if (!(user_avatar in power_user.personas)) {
console.log(`Creating a new persona ${user_avatar}`);
toastr.info(
'Creating a new persona for currently selected user name and avatar...',
'Persona not set for this avatar',
{ timeOut: 10000, extendedTimeOut: 20000, },
);
if (power_user.persona_show_notifications) {
toastr.info(
'Creating a new persona for currently selected user name and avatar...',
'Persona not set for this avatar',
{ timeOut: 10000, extendedTimeOut: 20000, },
);
}
power_user.personas[user_avatar] = name1;
power_user.persona_descriptions[user_avatar] = { description: '', position: persona_description_positions.BEFORE_CHAR };
}
@ -4855,7 +4880,9 @@ function lockUserNameToChat() {
saveMetadata();
saveSettingsDebounced();
console.log(`Locking persona for this chat ${user_avatar}`);
toastr.success(`User persona is locked to ${name1} in this chat`);
if (power_user.persona_show_notifications) {
toastr.success(`User persona is locked to ${name1} in this chat`);
}
updateUserLockIcon();
}
@ -5076,11 +5103,13 @@ async function getSettings(type) {
setWorldInfoSettings(settings, data);
api_server_textgenerationwebui =
settings.api_server_textgenerationwebui;
api_server_textgenerationwebui = settings.api_server_textgenerationwebui;
$("#textgenerationwebui_api_url_text").val(
api_server_textgenerationwebui
);
api_use_mancer_webui = settings.api_use_mancer_webui
$('#use-mancer-api-checkbox').prop("checked", api_use_mancer_webui);
$('#use-mancer-api-checkbox').trigger("change");
selected_button = settings.selected_button;
@ -5114,6 +5143,7 @@ async function saveSettings(type) {
active_group: active_group,
api_server: api_server,
api_server_textgenerationwebui: api_server_textgenerationwebui,
api_use_mancer_webui: api_use_mancer_webui,
preset_settings: preset_settings,
user_avatar: user_avatar,
amount_gen: amount_gen,
@ -7508,7 +7538,7 @@ $(document).ready(function () {
<h3>Delete the character?</h3>
<b>THIS IS PERMANENT!<br><br>
<label for="del_char_checkbox" class="checkbox_label justifyCenter">
<input type="checkbox" id="del_char_checkbox" checked />
<input type="checkbox" id="del_char_checkbox" />
<span>Also delete the chat files</span>
</label><br></b>`
);
@ -7691,16 +7721,28 @@ $(document).ready(function () {
}
});
$("#api_button_textgenerationwebui").click(function (e) {
$("#use-mancer-api-checkbox").on("change", function (e) {
const enabled = $("#use-mancer-api-checkbox").prop("checked");
$("#mancer-api-ui").toggle(enabled);
api_use_mancer_webui = enabled;
saveSettingsDebounced();
getStatus();
});
$("#api_button_textgenerationwebui").click(async function (e) {
e.stopPropagation();
if ($("#textgenerationwebui_api_url_text").val() != "") {
let value = formatKoboldUrl($("#textgenerationwebui_api_url_text").val().trim());
let value = formatTextGenURL($("#textgenerationwebui_api_url_text").val().trim())
if (!value) {
callPopup('Please enter a valid URL.', 'text');
callPopup('Please enter a valid URL.<br/>WebUI URLs should end with <tt>/api</tt>', 'text');
return;
}
const mancer_key = $("#api_key_mancer").val().trim();
if (mancer_key.length) {
await writeSecret(SECRET_KEYS.MANCER, mancer_key);
}
$("#textgenerationwebui_api_url_text").val(value);
$("#api_loading_textgenerationwebui").css("display", "inline-block");
$("#api_button_textgenerationwebui").css("display", "none");

View File

@ -534,12 +534,14 @@ export function dragElement(elmnt) {
if (elmntHeader.length) {
elmntHeader.off('mousedown').on('mousedown', (e) => {
hasBeenDraggedByUser = true
observer.observe(elmnt.get(0), { attributes: true, attributeFilter: ['style'] });
dragMouseDown(e);
});
$(elmnt).off('mousedown').on('mousedown', () => { isMouseDown = true })
} else {
elmnt.off('mousedown').on('mousedown', dragMouseDown);
$(elmnt).off('mousedown').on('mousedown', () => {
isMouseDown = true
observer.observe(elmnt.get(0), { attributes: true, attributeFilter: ['style'] });
})
}
const observer = new MutationObserver((mutations) => {
@ -618,7 +620,7 @@ export function dragElement(elmnt) {
}
//prevent resizing from top left into the top bar
if (top <= 40 && maxX >= topBarFirstX && left <= topBarFirstX
if (top < 40 && maxX >= topBarFirstX && left <= topBarFirstX
) {
console.debug('prevent topbar underlap resize')
elmnt.css('width', width - 1 + "px");
@ -674,8 +676,6 @@ export function dragElement(elmnt) {
}
});
observer.observe(elmnt.get(0), { attributes: true, attributeFilter: ['style'] });
function dragMouseDown(e) {
if (e) {
@ -745,6 +745,7 @@ export function dragElement(elmnt) {
$("body").css("overflow", "");
// Clear the "data-dragged" attribute
elmnt.attr('data-dragged', 'false');
observer.disconnect()
console.debug(`Saving ${elmntName} UI position`)
saveSettingsDebounced();

View File

@ -0,0 +1,108 @@
import { characters, getCharacters, saveSettingsDebounced, handleDeleteCharacter } from "../../../script.js";
let is_bulk_edit = false;
/**
* Toggles bulk edit mode on/off when the edit button is clicked.
*/
function onEditButtonClick() {
console.log("Edit button clicked");
// toggle bulk edit mode
if (is_bulk_edit) {
disableBulkSelect();
// hide the delete button
$("#bulkDeleteButton").hide();
is_bulk_edit = false;
} else {
enableBulkSelect();
// show the delete button
$("#bulkDeleteButton").show();
is_bulk_edit = true;
}
}
/**
* Deletes the character with the given chid.
*
* @param {string} this_chid - The chid of the character to delete.
*/
async function deleteCharacter(this_chid) {
await handleDeleteCharacter("del_ch", this_chid);
}
/**
* Deletes all characters that have been selected via the bulk checkboxes.
*/
async function onDeleteButtonClick() {
console.log("Delete button clicked");
// Create a mapping of chid to avatar
let toDelete = [];
$(".bulk_select_checkbox:checked").each((i, el) => {
const chid = $(el).parent().attr("chid");
const avatar = characters[chid].avatar;
// Add the avatar to the list of avatars to delete
toDelete.push(avatar);
});
// Delete the characters
for (const avatar of toDelete) {
console.log(`Deleting character with avatar ${avatar}`);
await getCharacters();
//chid should be the key of the character with the given avatar
const chid = Object.keys(characters).find((key) => characters[key].avatar === avatar);
console.log(`Deleting character with chid ${chid}`);
await deleteCharacter(chid);
}
}
/**
* Adds the bulk edit and delete buttons to the UI.
*/
function addButtons() {
const editButton = $(
"<i id='bulkEditButton' class='fa-solid fa-edit menu_button bulkEditButton' title='Bulk edit characters'></i>"
);
const deleteButton = $(
"<i id='bulkDeleteButton' class='fa-solid fa-trash menu_button bulkDeleteButton' title='Bulk delete characters' style='display: none;'></i>"
);
$("#charListGridToggle").after(editButton, deleteButton);
$("#bulkEditButton").on("click", onEditButtonClick);
$("#bulkDeleteButton").on("click", onDeleteButtonClick);
}
/**
* Enables bulk selection by adding a checkbox next to each character.
*/
function enableBulkSelect() {
$(".character_select").each((i, el) => {
const character = $(el).text();
const checkbox = $("<input type='checkbox' class='bulk_select_checkbox'>");
checkbox.on("change", () => {
// Do something when the checkbox is changed
});
$(el).prepend(checkbox);
});
// We also need to disable the default click event for the character_select divs
$(document).on("click", ".bulk_select_checkbox", function (event) {
event.stopImmediatePropagation();
});
}
/**
* Disables bulk selection by removing the checkboxes.
*/
function disableBulkSelect() {
$(".bulk_select_checkbox").remove();
}
/**
* Entry point that runs on page load.
*/
jQuery(async () => {
addButtons();
// loadSettings();
});

View File

@ -0,0 +1,11 @@
{
"display_name": "Bulk Card Editor",
"loading_order": 9,
"requires": [],
"optional": [],
"js": "index.js",
"css": "style.css",
"author": "city-unit",
"version": "1.0.0",
"homePage": "https://github.com/city-unit"
}

View File

@ -449,7 +449,7 @@ async function loadLiveChar() {
function handleImageChange() {
const imgElement = document.querySelector('img#expression-image.expression');
if (!imgElement) {
console.log("Cannot find addExpressionImage()");
return;
@ -459,6 +459,7 @@ function handleImageChange() {
previousSrc = imgElement.src;
// Method get IP of endpoint
const live2dResultFeedSrc = `${getApiUrl()}/api/live2d/result_feed`;
$('#expression-holder').css({ display: '' });
if (imgElement.src !== live2dResultFeedSrc) {
const expressionImageElement = document.querySelector('.expression_list_image');
@ -922,7 +923,7 @@ async function setExpression(character, expression, force) {
if (imgElement) {
console.log("setting value");
imgElement.src = getApiUrl() + '/api/live2d/result_feed';
}
}
}
}

View File

@ -1,6 +1,7 @@
import { getStringHash, debounce, waitUntilCondition, extractAllWords } from "../../utils.js";
import { getContext, getApiUrl, extension_settings, doExtrasFetch, modules } from "../../extensions.js";
import { eventSource, event_types, extension_prompt_types, generateQuietPrompt, is_send_press, saveSettingsDebounced, substituteParams } from "../../../script.js";
import { is_group_generating, selected_group } from "../../group-chats.js";
export { MODULE_NAME };
const MODULE_NAME = '1_memory';
@ -333,6 +334,10 @@ async function summarizeChat(context) {
async function summarizeChatMain(context, force) {
try {
// Wait for group to finish generating
if (selected_group) {
await waitUntilCondition(() => is_group_generating === false, 1000, 10);
}
// Wait for the send button to be released
waitUntilCondition(() => is_send_press === false, 30000, 100);
} catch {

View File

@ -27,7 +27,7 @@ import {
import { registerSlashCommand } from "./slash-commands.js";
import { delay, debounce } from "./utils.js";
import { delay } from "./utils.js";
export {
loadPowerUserSettings,
@ -184,6 +184,7 @@ let power_user = {
persona_description: '',
persona_description_position: persona_description_positions.BEFORE_CHAR,
persona_show_notifications: true,
custom_stopping_strings: '',
fuzzy_search: false,
@ -678,6 +679,7 @@ function loadPowerUserSettings(settings, data) {
$('#auto_swipe_blacklist_threshold').val(power_user.auto_swipe_blacklist_threshold);
$('#custom_stopping_strings').val(power_user.custom_stopping_strings);
$('#fuzzy_search_checkbox').prop("checked", power_user.fuzzy_search);
$('#persona_show_notifications').prop("checked", power_user.persona_show_notifications);
$("#console_log_prompts").prop("checked", power_user.console_log_prompts);
$('#auto_fix_generated_markdown').prop("checked", power_user.auto_fix_generated_markdown);
@ -1998,6 +2000,11 @@ $(document).ready(() => {
saveSettingsDebounced();
});
$('#persona_show_notifications').on('input', function () {
power_user.persona_show_notifications = !!$(this).prop('checked');
saveSettingsDebounced();
});
$(window).on('focus', function () {
browser_has_focus = true;
});

View File

@ -2,6 +2,7 @@ import { callPopup, getRequestHeaders } from "../script.js";
export const SECRET_KEYS = {
HORDE: 'api_key_horde',
MANCER: 'api_key_mancer',
OPENAI: 'api_key_openai',
NOVEL: 'api_key_novel',
CLAUDE: 'api_key_claude',
@ -11,6 +12,7 @@ export const SECRET_KEYS = {
const INPUT_MAP = {
[SECRET_KEYS.HORDE]: '#horde_api_key',
[SECRET_KEYS.MANCER]: '#api_key_mancer',
[SECRET_KEYS.OPENAI]: '#api_key_openai',
[SECRET_KEYS.NOVEL]: '#api_key_novel',
[SECRET_KEYS.CLAUDE]: '#api_key_claude',

View File

@ -10,6 +10,7 @@ export {
textgenerationwebui_settings,
loadTextGenSettings,
generateTextGenWithStreaming,
formatTextGenURL,
}
const textgenerationwebui_settings = {
@ -94,6 +95,16 @@ function selectPreset(name) {
saveSettingsDebounced();
}
function formatTextGenURL(value) {
try {
const url = new URL(value);
if (url.pathname.endsWith('/api')) {
return url.toString();
}
} catch { } // Try and Catch both fall through to the same return.
return null;
}
function convertPresets(presets) {
return Array.isArray(presets) ? presets.map(JSON.parse) : [];
}

View File

@ -3040,9 +3040,22 @@ h5 {
opacity: 0.4;
}
.PastChat_cross:hover {
color: red;
filter: drop-shadow(0 0 2px red);
-webkit-animation: infinite-spinning 1s ease-out 0s infinite normal;
animation: infinite-spinning 1s ease-out 0s infinite normal;
}
/* HEINOUS */
@keyframes infinite-spinning {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#export_character_div {
@ -4409,6 +4422,10 @@ toolcool-color-picker {
width: 50px;
}
.indent20p {
margin-left: 20px;
}
.wi-enter-footer-text {
font-size: calc(var(--mainFontSize) * 0.8);
color: var(--SmartThemeBodyColor);

View File

@ -146,6 +146,14 @@ let response_getstatus;
let first_run = true;
function get_mancer_headers() {
const api_key_mancer = readSecret(SECRET_KEYS.MANCER);
return api_key_mancer ? { "X-API-KEY": api_key_mancer} : {};
}
//RossAscends: Added function to format dates used in files and chat timestamps to a humanized format.
//Mostly I wanted this to be for file names, but couldn't figure out exactly where the filename save code was as everything seemed to be connected.
//During testing, this performs the same as previous date.now() structure.
@ -640,13 +648,22 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
signal: controller.signal,
};
if (request.body.use_mancer) {
args.headers = Object.assign(args.headers, get_mancer_headers());
}
try {
const data = await postAsync(api_server + "/v1/generate", args);
console.log(data);
return response_generate.send(data);
} catch (error) {
retval = { error: true, status: error.status, response: error.statusText };
console.log(error);
return response_generate.send({ error: true });
try {
retval.response = await error.json();
retval.response = retval.response.result;
} catch {}
return response_generate.send(retval);
}
}
});
@ -710,6 +727,11 @@ app.post("/getstatus", jsonParser, async function (request, response_getstatus =
var args = {
headers: { "Content-Type": "application/json" }
};
if (main_api == 'textgenerationwebui' && request.body.use_mancer) {
args.headers = Object.assign(args.headers, get_mancer_headers());
}
var url = api_server + "/v1/model";
let version = '';
let koboldVersion = {};
@ -730,18 +752,18 @@ app.post("/getstatus", jsonParser, async function (request, response_getstatus =
};
}
}
client.get(url, args, function (data, response) {
client.get(url, args, async function (data, response) {
if (typeof data !== 'object') {
data = {};
}
if (response.statusCode == 200) {
data.version = version;
data.koboldVersion = koboldVersion;
if (data.result != "ReadOnly") {
} else {
if (data.result == "ReadOnly") {
data.result = "no_connection";
}
} else {
data.response = data.result;
data.result = "no_connection";
}
response_getstatus.send(data);
@ -3453,6 +3475,10 @@ app.post("/tokenize_via_api", jsonParser, async function (request, response) {
body: JSON.stringify({ "prompt": text }),
headers: { "Content-Type": "application/json" }
};
if (main_api == 'textgenerationwebui' && request.body.use_mancer) {
args.headers = Object.assign(args.headers, get_mancer_headers());
}
const data = await postAsync(api_server + "/v1/token-count", args);
console.log(data);
@ -3659,6 +3685,7 @@ const SECRETS_FILE = './secrets.json';
const SETTINGS_FILE = './public/settings.json';
const SECRET_KEYS = {
HORDE: 'api_key_horde',
MANCER: 'api_key_mancer',
OPENAI: 'api_key_openai',
NOVEL: 'api_key_novel',
CLAUDE: 'api_key_claude',