Merge branch 'staging' of http://github.com/cohee1207/SillyTavern into staging
This commit is contained in:
commit
1b7973ec13
|
@ -291,7 +291,6 @@ SillyTavern 会将 API 密钥保存在目录中的 `secrets.json` 文件内。
|
||||||
* RossAscends' additions: AGPL v3
|
* RossAscends' additions: AGPL v3
|
||||||
* Portions of CncAnon's TavernAITurbo mod: Unknown license
|
* Portions of CncAnon's TavernAITurbo mod: Unknown license
|
||||||
* kingbri's various commits and suggestions (https://github.com/bdashore3)
|
* kingbri's various commits and suggestions (https://github.com/bdashore3)
|
||||||
* BlipRanger's miscellaneous UI & extension modifications (https://github.com/BlipRanger)
|
|
||||||
* Waifu mode inspired by the work of PepperTaco (https://github.com/peppertaco/Tavern/)
|
* Waifu mode inspired by the work of PepperTaco (https://github.com/peppertaco/Tavern/)
|
||||||
* Thanks Pygmalion University for being awesome testers and suggesting cool features!
|
* Thanks Pygmalion University for being awesome testers and suggesting cool features!
|
||||||
* Thanks oobabooga for compiling presets for TextGen
|
* Thanks oobabooga for compiling presets for TextGen
|
||||||
|
|
|
@ -293,7 +293,6 @@ GNU Affero General Public License for more details.**
|
||||||
* RossAscends' additions: AGPL v3
|
* RossAscends' additions: AGPL v3
|
||||||
* Portions of CncAnon's TavernAITurbo mod: Unknown license
|
* Portions of CncAnon's TavernAITurbo mod: Unknown license
|
||||||
* kingbri's various commits and suggestions (<https://github.com/bdashore3>)
|
* kingbri's various commits and suggestions (<https://github.com/bdashore3>)
|
||||||
* BlipRanger's miscellaneous UI & extension modifications (<https://github.com/BlipRanger>)
|
|
||||||
* Waifu mode inspired by the work of PepperTaco (<https://github.com/peppertaco/Tavern/>)
|
* Waifu mode inspired by the work of PepperTaco (<https://github.com/peppertaco/Tavern/>)
|
||||||
* Thanks Pygmalion University for being awesome testers and suggesting cool features!
|
* Thanks Pygmalion University for being awesome testers and suggesting cool features!
|
||||||
* Thanks oobabooga for compiling presets for TextGen
|
* Thanks oobabooga for compiling presets for TextGen
|
||||||
|
@ -306,3 +305,4 @@ GNU Affero General Public License for more details.**
|
||||||
* 10K Discord Users Celebratory Background by @kallmeflocc
|
* 10K Discord Users Celebratory Background by @kallmeflocc
|
||||||
* Default content (characters and lore books) provided by @OtisAlejandro, @RossAscends and @kallmeflocc
|
* Default content (characters and lore books) provided by @OtisAlejandro, @RossAscends and @kallmeflocc
|
||||||
* Korean translation by @doloroushyeonse
|
* Korean translation by @doloroushyeonse
|
||||||
|
* k_euler_a support for Horde by <https://github.com/Teashrock>
|
||||||
|
|
|
@ -26,4 +26,5 @@ secrets.json
|
||||||
/dist
|
/dist
|
||||||
/backups/
|
/backups/
|
||||||
public/movingUI/
|
public/movingUI/
|
||||||
|
public/QuickReplies/
|
||||||
content.log
|
content.log
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.9.2",
|
"version": "1.9.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sillytavern",
|
"name": "sillytavern",
|
||||||
"version": "1.9.2",
|
"version": "1.9.3",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dqbd/tiktoken": "^1.0.2",
|
"@dqbd/tiktoken": "^1.0.2",
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
"url": "https://github.com/SillyTavern/SillyTavern.git"
|
||||||
},
|
},
|
||||||
"version": "1.9.2",
|
"version": "1.9.3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"pkg": "pkg --compress Gzip --no-bytecode --public ."
|
"pkg": "pkg --compress Gzip --no-bytecode --public ."
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "Default",
|
||||||
|
"quickReplyEnabled": true,
|
||||||
|
"quickReplySlots": [
|
||||||
|
{
|
||||||
|
"mes": "/?",
|
||||||
|
"label": "HELP",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mes": "/newchat",
|
||||||
|
"label": "New Chat",
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mes": "/bgcol",
|
||||||
|
"label": "Match UI to Background",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"numberOfSlots": 3,
|
||||||
|
"selectedPreset": "Default"
|
||||||
|
}
|
|
@ -683,6 +683,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="range-block" data-source="claude">
|
||||||
|
<div class="range-block-title" data-i18n="Assistant Prefill">
|
||||||
|
Assistant Prefill
|
||||||
|
</div>
|
||||||
|
<div class="wide100p">
|
||||||
|
<input type="text" id="claude_assistant_prefill" class="text_pole" placeholder="Start Claude's answer with...">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -737,6 +737,9 @@ let token;
|
||||||
|
|
||||||
var PromptArrayItemForRawPromptDisplay;
|
var PromptArrayItemForRawPromptDisplay;
|
||||||
|
|
||||||
|
export let active_character = ""
|
||||||
|
export let active_group = ""
|
||||||
|
|
||||||
export function getRequestHeaders() {
|
export function getRequestHeaders() {
|
||||||
return {
|
return {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
@ -786,6 +789,14 @@ function checkOnlineStatus() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setActiveCharacter(character) {
|
||||||
|
active_character = character;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setActiveGroup(group) {
|
||||||
|
active_group = group;
|
||||||
|
}
|
||||||
|
|
||||||
async function getStatus() {
|
async function getStatus() {
|
||||||
if (is_get_status) {
|
if (is_get_status) {
|
||||||
if (main_api == "koboldhorde") {
|
if (main_api == "koboldhorde") {
|
||||||
|
@ -5009,6 +5020,10 @@ async function getSettings(type) {
|
||||||
highlightSelectedAvatar();
|
highlightSelectedAvatar();
|
||||||
setPersonaDescription();
|
setPersonaDescription();
|
||||||
|
|
||||||
|
//Load the active character and group
|
||||||
|
active_character = settings.active_character;
|
||||||
|
active_group = settings.active_group;
|
||||||
|
|
||||||
//Load the API server URL from settings
|
//Load the API server URL from settings
|
||||||
api_server = settings.api_server;
|
api_server = settings.api_server;
|
||||||
$("#api_url_text").val(api_server);
|
$("#api_url_text").val(api_server);
|
||||||
|
@ -5049,6 +5064,8 @@ async function saveSettings(type) {
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
firstRun: firstRun,
|
firstRun: firstRun,
|
||||||
username: name1,
|
username: name1,
|
||||||
|
active_character: active_character,
|
||||||
|
active_group: active_group,
|
||||||
api_server: api_server,
|
api_server: api_server,
|
||||||
api_server_textgenerationwebui: api_server_textgenerationwebui,
|
api_server_textgenerationwebui: api_server_textgenerationwebui,
|
||||||
preset_settings: preset_settings,
|
preset_settings: preset_settings,
|
||||||
|
|
|
@ -13,6 +13,10 @@ import {
|
||||||
menu_type,
|
menu_type,
|
||||||
max_context,
|
max_context,
|
||||||
saveSettingsDebounced,
|
saveSettingsDebounced,
|
||||||
|
active_group,
|
||||||
|
active_character,
|
||||||
|
setActiveGroup,
|
||||||
|
setActiveCharacter,
|
||||||
} from "../script.js";
|
} from "../script.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -330,11 +334,21 @@ export function RA_CountCharTokens() {
|
||||||
characterStatsHandler(characters, this_chid);
|
characterStatsHandler(characters, this_chid);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//Auto Load Last Charcter -- (fires when active_character is defined and auto_load_chat is true)
|
/**
|
||||||
|
* Auto load chat with the last active character or group.
|
||||||
|
* Fires when active_character is defined and auto_load_chat is true.
|
||||||
|
* The function first tries to find a character with a specific ID from the global settings.
|
||||||
|
* If it doesn't exist, it tries to find a group with a specific grid from the global settings.
|
||||||
|
* If the character list hadn't been loaded yet, it calls itself again after 100ms delay.
|
||||||
|
* The character or group is selected (clicked) if it is found.
|
||||||
|
*/
|
||||||
async function RA_autoloadchat() {
|
async function RA_autoloadchat() {
|
||||||
if (document.getElementById('CharID0') !== null) {
|
if (document.getElementById('CharID0') !== null) {
|
||||||
var charToAutoLoad = document.getElementById('CharID' + LoadLocal('ActiveChar'));
|
// active character is the name, we should look it up in the character list and get the id
|
||||||
let groupToAutoLoad = document.querySelector(`.group_select[grid="${LoadLocal('ActiveGroup')}"]`);
|
let active_character_id = Object.keys(characters).find(key => characters[key].avatar === active_character);
|
||||||
|
|
||||||
|
var charToAutoLoad = document.getElementById('CharID' + active_character_id);
|
||||||
|
let groupToAutoLoad = document.querySelector(`.group_select[grid="${active_group}"]`);
|
||||||
if (charToAutoLoad != null) {
|
if (charToAutoLoad != null) {
|
||||||
$(charToAutoLoad).click();
|
$(charToAutoLoad).click();
|
||||||
}
|
}
|
||||||
|
@ -342,7 +356,7 @@ async function RA_autoloadchat() {
|
||||||
$(groupToAutoLoad).click();
|
$(groupToAutoLoad).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the charcter list hadn't been loaded yet, try again.
|
// if the character list hadn't been loaded yet, try again.
|
||||||
} else { setTimeout(RA_autoloadchat, 100); }
|
} else { setTimeout(RA_autoloadchat, 100); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,16 +917,22 @@ $("document").ready(function () {
|
||||||
$("#rm_button_characters").click(function () { SaveLocal('SelectedNavTab', 'rm_button_characters'); });
|
$("#rm_button_characters").click(function () { SaveLocal('SelectedNavTab', 'rm_button_characters'); });
|
||||||
|
|
||||||
// when a char is selected from the list, save them as the auto-load character for next page load
|
// when a char is selected from the list, save them as the auto-load character for next page load
|
||||||
|
|
||||||
|
// when a char is selected from the list, save their name as the auto-load character for next page load
|
||||||
$(document).on("click", ".character_select", function () {
|
$(document).on("click", ".character_select", function () {
|
||||||
SaveLocal('ActiveChar', $(this).attr('chid'));
|
setActiveCharacter($(this).find('.avatar').attr('title'));
|
||||||
SaveLocal('ActiveGroup', null);
|
setActiveGroup(null);
|
||||||
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on("click", ".group_select", function () {
|
$(document).on("click", ".group_select", function () {
|
||||||
SaveLocal('ActiveChar', null);
|
setActiveCharacter(null);
|
||||||
SaveLocal('ActiveGroup', $(this).data('id'));
|
setActiveGroup($(this).data('id'));
|
||||||
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//this makes the chat input text area resize vertically to match the text size (limited by CSS at 50% window height)
|
//this makes the chat input text area resize vertically to match the text size (limited by CSS at 50% window height)
|
||||||
$('#send_textarea').on('input', function () {
|
$('#send_textarea').on('input', function () {
|
||||||
this.style.height = '40px';
|
this.style.height = '40px';
|
||||||
|
|
|
@ -1,19 +1,48 @@
|
||||||
import { saveSettingsDebounced } from "../../../script.js";
|
import { saveSettingsDebounced, callPopup, getRequestHeaders } from "../../../script.js";
|
||||||
import { getContext, extension_settings } from "../../extensions.js";
|
import { getContext, extension_settings } from "../../extensions.js";
|
||||||
import { initScrollHeight, resetScrollHeight } from "../../utils.js";
|
import { initScrollHeight, resetScrollHeight } from "../../utils.js";
|
||||||
|
|
||||||
|
|
||||||
export { MODULE_NAME };
|
export { MODULE_NAME };
|
||||||
|
|
||||||
const MODULE_NAME = 'quick-reply';
|
const MODULE_NAME = 'quick-reply';
|
||||||
const UPDATE_INTERVAL = 1000;
|
const UPDATE_INTERVAL = 1000;
|
||||||
|
let presets = [];
|
||||||
|
let selected_preset = '';
|
||||||
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
quickReplyEnabled: false,
|
quickReplyEnabled: true,
|
||||||
numberOfSlots: 5,
|
numberOfSlots: 5,
|
||||||
quickReplySlots: [],
|
quickReplySlots: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadSettings() {
|
//method from worldinfo
|
||||||
|
async function updateQuickReplyPresetList() {
|
||||||
|
var result = await fetch("/getsettings", {
|
||||||
|
method: "POST",
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: JSON.stringify({}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.ok) {
|
||||||
|
var data = await result.json();
|
||||||
|
presets = data.quickReplyPresets?.length ? data.quickReplyPresets : [];
|
||||||
|
console.log(presets)
|
||||||
|
$("#quickReplyPresets").find('option[value!=""]').remove();
|
||||||
|
|
||||||
|
|
||||||
|
if (presets !== undefined) {
|
||||||
|
presets.forEach((item, i) => {
|
||||||
|
$("#quickReplyPresets").append(`<option value='${item.name}'${selected_preset.includes(item.name) ? ' selected' : ''}>${item.name}</option>`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadSettings(type) {
|
||||||
|
if (type === 'init') {
|
||||||
|
await updateQuickReplyPresetList()
|
||||||
|
}
|
||||||
if (Object.keys(extension_settings.quickReply).length === 0) {
|
if (Object.keys(extension_settings.quickReply).length === 0) {
|
||||||
Object.assign(extension_settings.quickReply, defaultSettings);
|
Object.assign(extension_settings.quickReply, defaultSettings);
|
||||||
}
|
}
|
||||||
|
@ -111,6 +140,51 @@ async function moduleWorker() {
|
||||||
if (extension_settings.quickReply.quickReplyEnabled === true) {
|
if (extension_settings.quickReply.quickReplyEnabled === true) {
|
||||||
$('#quickReplyBar').toggle(getContext().onlineStatus !== 'no_connection');
|
$('#quickReplyBar').toggle(getContext().onlineStatus !== 'no_connection');
|
||||||
}
|
}
|
||||||
|
if (extension_settings.quickReply.selectedPreset) {
|
||||||
|
selected_preset = extension_settings.quickReply.selectedPreset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveQuickReplyPreset() {
|
||||||
|
const name = await callPopup('Enter a name for the Quick Reply Preset:', 'input');
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const quickReplyPreset = {
|
||||||
|
name: name,
|
||||||
|
quickReplyEnabled: extension_settings.quickReply.quickReplyEnabled,
|
||||||
|
quickReplySlots: extension_settings.quickReply.quickReplySlots,
|
||||||
|
numberOfSlots: extension_settings.quickReply.numberOfSlots,
|
||||||
|
selectedPreset: name
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch('/savequickreply', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: JSON.stringify(quickReplyPreset)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const quickReplyPresetIndex = presets.findIndex(x => x.name == name);
|
||||||
|
|
||||||
|
if (quickReplyPresetIndex == -1) {
|
||||||
|
presets.push(quickReplyPreset);
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.selected = true;
|
||||||
|
option.value = name;
|
||||||
|
option.innerText = name;
|
||||||
|
$('#quickReplyPresets').append(option);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
presets[quickReplyPresetIndex] = quickReplyPreset;
|
||||||
|
$(`#quickReplyPresets option[value="${name}"]`).attr('selected', true);
|
||||||
|
}
|
||||||
|
saveSettingsDebounced();
|
||||||
|
} else {
|
||||||
|
toastr.warning('Failed to save Quick Reply Preset.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onQuickReplyNumberOfSlotsInput() {
|
async function onQuickReplyNumberOfSlotsInput() {
|
||||||
|
@ -178,6 +252,27 @@ function generateQuickReplyElements() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function applyQuickReplyPreset(name) {
|
||||||
|
const quickReplyPreset = presets.find(x => x.name == name);
|
||||||
|
|
||||||
|
if (!quickReplyPreset) {
|
||||||
|
console.log(`error, QR preset '${name}' not found`)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension_settings.quickReply = quickReplyPreset;
|
||||||
|
extension_settings.quickReply.selectedPreset = name;
|
||||||
|
saveSettingsDebounced()
|
||||||
|
loadSettings('init')
|
||||||
|
addQuickReplyBar();
|
||||||
|
moduleWorker();
|
||||||
|
|
||||||
|
$(`#quickReplyPresets option[value="${name}"]`).attr('selected', true);
|
||||||
|
|
||||||
|
console.debug('QR Preset applied: ' + name);
|
||||||
|
//loadMovingUIState()
|
||||||
|
}
|
||||||
|
|
||||||
jQuery(async () => {
|
jQuery(async () => {
|
||||||
|
|
||||||
moduleWorker();
|
moduleWorker();
|
||||||
|
@ -190,11 +285,18 @@ jQuery(async () => {
|
||||||
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
<div class="inline-drawer-icon fa-solid fa-circle-chevron-down down"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-drawer-content">
|
<div class="inline-drawer-content">
|
||||||
<label class="checkbox_label marginBot10">
|
<div class="flex-container ">
|
||||||
|
<label class="checkbox_label marginBot10 wide100p flexnowrap">
|
||||||
<input id="quickReplyEnabled" type="checkbox" />
|
<input id="quickReplyEnabled" type="checkbox" />
|
||||||
Enable Quick Replies
|
Enable Quick Replies
|
||||||
</label>
|
</label>
|
||||||
|
<div class="flex-container flexnowrap wide100p">
|
||||||
|
<select id="quickReplyPresets" name="quickreply-preset">
|
||||||
|
</select>
|
||||||
|
<i id="quickReplyPresetSaveButton" class="fa-solid fa-save"></i>
|
||||||
|
</div>
|
||||||
<label for="quickReplyNumberOfSlots">Number of slots:</label>
|
<label for="quickReplyNumberOfSlots">Number of slots:</label>
|
||||||
|
</div>
|
||||||
<div class="flex-container flexGap5 flexnowrap">
|
<div class="flex-container flexGap5 flexnowrap">
|
||||||
<input id="quickReplyNumberOfSlots" class="text_pole" type="number" min="1" max="100" value="" />
|
<input id="quickReplyNumberOfSlots" class="text_pole" type="number" min="1" max="100" value="" />
|
||||||
<div class="menu_button menu_button_icon" id="quickReplyNumberOfSlotsApply">
|
<div class="menu_button menu_button_icon" id="quickReplyNumberOfSlotsApply">
|
||||||
|
@ -212,8 +314,17 @@ jQuery(async () => {
|
||||||
|
|
||||||
$('#quickReplyEnabled').on('input', onQuickReplyEnabledInput);
|
$('#quickReplyEnabled').on('input', onQuickReplyEnabledInput);
|
||||||
$('#quickReplyNumberOfSlotsApply').on('click', onQuickReplyNumberOfSlotsInput);
|
$('#quickReplyNumberOfSlotsApply').on('click', onQuickReplyNumberOfSlotsInput);
|
||||||
|
$("#quickReplyPresetSaveButton").on('click', saveQuickReplyPreset);
|
||||||
|
|
||||||
await loadSettings();
|
$("#quickReplyPresets").on('change', async function () {
|
||||||
|
const quickReplyPresetSelected = $(this).find(':selected').val();
|
||||||
|
extension_settings.quickReplyPreset = quickReplyPresetSelected;
|
||||||
|
applyQuickReplyPreset(quickReplyPresetSelected);
|
||||||
|
saveSettingsDebounced();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
await loadSettings('init');
|
||||||
addQuickReplyBar();
|
addQuickReplyBar();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -90,13 +90,6 @@ function loadNovelSettings(settings) {
|
||||||
nai_settings.cfg_scale = settings.cfg_scale;
|
nai_settings.cfg_scale = settings.cfg_scale;
|
||||||
nai_settings.streaming_novel = !!settings.streaming_novel;
|
nai_settings.streaming_novel = !!settings.streaming_novel;
|
||||||
loadNovelSettingsUi(nai_settings);
|
loadNovelSettingsUi(nai_settings);
|
||||||
|
|
||||||
// reload the preset to migrate any new settings
|
|
||||||
for (const key of Object.keys(nai_settings)) {
|
|
||||||
if (typeof nai_settings[key] === 'number' && Number.isNaN(nai_settings[key])) {
|
|
||||||
$("#settings_perset_novel").trigger("change");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const phraseRepPenStrings = [
|
const phraseRepPenStrings = [
|
||||||
|
@ -109,7 +102,7 @@ const phraseRepPenStrings = [
|
||||||
]
|
]
|
||||||
|
|
||||||
function getPhraseRepPenString(phraseRepPenCounter) {
|
function getPhraseRepPenString(phraseRepPenCounter) {
|
||||||
if (phraseRepPenCounter < 1 || phraseRepPenCounter > F5) {
|
if (phraseRepPenCounter < 1 || phraseRepPenCounter > 5) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return phraseRepPenStrings[phraseRepPenCounter];
|
return phraseRepPenStrings[phraseRepPenCounter];
|
||||||
|
|
|
@ -143,6 +143,7 @@ const default_settings = {
|
||||||
api_url_scale: '',
|
api_url_scale: '',
|
||||||
show_external_models: false,
|
show_external_models: false,
|
||||||
proxy_password: '',
|
proxy_password: '',
|
||||||
|
assistant_prefill: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
const oai_settings = {
|
const oai_settings = {
|
||||||
|
@ -180,6 +181,7 @@ const oai_settings = {
|
||||||
api_url_scale: '',
|
api_url_scale: '',
|
||||||
show_external_models: false,
|
show_external_models: false,
|
||||||
proxy_password: '',
|
proxy_password: '',
|
||||||
|
assistant_prefill: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
let openai_setting_names;
|
let openai_setting_names;
|
||||||
|
@ -775,6 +777,7 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
|
||||||
if (isClaude) {
|
if (isClaude) {
|
||||||
generate_data['use_claude'] = true;
|
generate_data['use_claude'] = true;
|
||||||
generate_data['top_k'] = parseFloat(oai_settings.top_k_openai);
|
generate_data['top_k'] = parseFloat(oai_settings.top_k_openai);
|
||||||
|
generate_data['assistant_prefill'] = substituteParams(oai_settings.assistant_prefill);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOpenRouter) {
|
if (isOpenRouter) {
|
||||||
|
@ -1109,6 +1112,7 @@ function loadOpenAISettings(data, settings) {
|
||||||
oai_settings.api_url_scale = settings.api_url_scale ?? default_settings.api_url_scale;
|
oai_settings.api_url_scale = settings.api_url_scale ?? default_settings.api_url_scale;
|
||||||
oai_settings.show_external_models = settings.show_external_models ?? default_settings.show_external_models;
|
oai_settings.show_external_models = settings.show_external_models ?? default_settings.show_external_models;
|
||||||
oai_settings.proxy_password = settings.proxy_password ?? default_settings.proxy_password;
|
oai_settings.proxy_password = settings.proxy_password ?? default_settings.proxy_password;
|
||||||
|
oai_settings.assistant_prefill = settings.assistant_prefill ?? default_settings.assistant_prefill;
|
||||||
|
|
||||||
if (settings.nsfw_toggle !== undefined) oai_settings.nsfw_toggle = !!settings.nsfw_toggle;
|
if (settings.nsfw_toggle !== undefined) oai_settings.nsfw_toggle = !!settings.nsfw_toggle;
|
||||||
if (settings.keep_example_dialogue !== undefined) oai_settings.keep_example_dialogue = !!settings.keep_example_dialogue;
|
if (settings.keep_example_dialogue !== undefined) oai_settings.keep_example_dialogue = !!settings.keep_example_dialogue;
|
||||||
|
@ -1121,6 +1125,7 @@ function loadOpenAISettings(data, settings) {
|
||||||
$('#stream_toggle').prop('checked', oai_settings.stream_openai);
|
$('#stream_toggle').prop('checked', oai_settings.stream_openai);
|
||||||
$('#api_url_scale').val(oai_settings.api_url_scale);
|
$('#api_url_scale').val(oai_settings.api_url_scale);
|
||||||
$('#openai_proxy_password').val(oai_settings.proxy_password);
|
$('#openai_proxy_password').val(oai_settings.proxy_password);
|
||||||
|
$('#claude_assistant_prefill').val(oai_settings.assistant_prefill);
|
||||||
|
|
||||||
$('#model_openai_select').val(oai_settings.openai_model);
|
$('#model_openai_select').val(oai_settings.openai_model);
|
||||||
$(`#model_openai_select option[value="${oai_settings.openai_model}"`).attr('selected', true);
|
$(`#model_openai_select option[value="${oai_settings.openai_model}"`).attr('selected', true);
|
||||||
|
@ -1323,6 +1328,7 @@ async function saveOpenAIPreset(name, settings) {
|
||||||
stream_openai: settings.stream_openai,
|
stream_openai: settings.stream_openai,
|
||||||
api_url_scale: settings.api_url_scale,
|
api_url_scale: settings.api_url_scale,
|
||||||
show_external_models: settings.show_external_models,
|
show_external_models: settings.show_external_models,
|
||||||
|
assistant_prefill: settings.assistant_prefill,
|
||||||
};
|
};
|
||||||
|
|
||||||
const savePresetSettings = await fetch(`/savepreset_openai?name=${name}`, {
|
const savePresetSettings = await fetch(`/savepreset_openai?name=${name}`, {
|
||||||
|
@ -1656,6 +1662,7 @@ function onSettingsPresetChange() {
|
||||||
api_url_scale: ['#api_url_scale', 'api_url_scale', false],
|
api_url_scale: ['#api_url_scale', 'api_url_scale', false],
|
||||||
show_external_models: ['#openai_show_external_models', 'show_external_models', true],
|
show_external_models: ['#openai_show_external_models', 'show_external_models', true],
|
||||||
proxy_password: ['#openai_proxy_password', 'proxy_password', false],
|
proxy_password: ['#openai_proxy_password', 'proxy_password', false],
|
||||||
|
assistant_prefill: ['#claude_assistant_prefill', 'assistant_prefill', false],
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [key, [selector, setting, isCheckbox]] of Object.entries(settingsToUpdate)) {
|
for (const [key, [selector, setting, isCheckbox]] of Object.entries(settingsToUpdate)) {
|
||||||
|
@ -2206,6 +2213,11 @@ $(document).ready(function () {
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#claude_assistant_prefill').on('input', function () {
|
||||||
|
oai_settings.assistant_prefill = $(this).val();
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
$("#api_button_openai").on("click", onConnectButtonClick);
|
$("#api_button_openai").on("click", onConnectButtonClick);
|
||||||
$("#openai_reverse_proxy").on("input", onReverseProxyInput);
|
$("#openai_reverse_proxy").on("input", onReverseProxyInput);
|
||||||
$("#model_openai_select").on("change", onModelChange);
|
$("#model_openai_select").on("change", onModelChange);
|
||||||
|
|
26
server.js
26
server.js
|
@ -290,6 +290,7 @@ const directories = {
|
||||||
instruct: 'public/instruct',
|
instruct: 'public/instruct',
|
||||||
context: 'public/context',
|
context: 'public/context',
|
||||||
backups: 'backups/',
|
backups: 'backups/',
|
||||||
|
quickreplies: 'public/QuickReplies'
|
||||||
};
|
};
|
||||||
|
|
||||||
// CSRF Protection //
|
// CSRF Protection //
|
||||||
|
@ -1600,6 +1601,8 @@ app.post('/getsettings', jsonParser, (request, response) => {
|
||||||
|
|
||||||
const themes = readAndParseFromDirectory(directories.themes);
|
const themes = readAndParseFromDirectory(directories.themes);
|
||||||
const movingUIPresets = readAndParseFromDirectory(directories.movingUI);
|
const movingUIPresets = readAndParseFromDirectory(directories.movingUI);
|
||||||
|
const quickReplyPresets = readAndParseFromDirectory(directories.quickreplies);
|
||||||
|
|
||||||
const instruct = readAndParseFromDirectory(directories.instruct);
|
const instruct = readAndParseFromDirectory(directories.instruct);
|
||||||
const context = readAndParseFromDirectory(directories.context);
|
const context = readAndParseFromDirectory(directories.context);
|
||||||
|
|
||||||
|
@ -1616,6 +1619,7 @@ app.post('/getsettings', jsonParser, (request, response) => {
|
||||||
textgenerationwebui_preset_names,
|
textgenerationwebui_preset_names,
|
||||||
themes,
|
themes,
|
||||||
movingUIPresets,
|
movingUIPresets,
|
||||||
|
quickReplyPresets,
|
||||||
instruct,
|
instruct,
|
||||||
context,
|
context,
|
||||||
enable_extensions: enableExtensions,
|
enable_extensions: enableExtensions,
|
||||||
|
@ -1672,6 +1676,17 @@ app.post('/savemovingui', jsonParser, (request, response) => {
|
||||||
return response.sendStatus(200);
|
return response.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.post('/savequickreply', jsonParser, (request, response) => {
|
||||||
|
if (!request.body || !request.body.name) {
|
||||||
|
return response.sendStatus(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const filename = path.join(directories.quickreplies, sanitize(request.body.name) + '.json');
|
||||||
|
fs.writeFileSync(filename, JSON.stringify(request.body, null, 4), 'utf8');
|
||||||
|
|
||||||
|
return response.sendStatus(200);
|
||||||
|
});
|
||||||
|
|
||||||
function convertWorldInfoToCharacterBook(name, entries) {
|
function convertWorldInfoToCharacterBook(name, entries) {
|
||||||
const result = { entries: [], name };
|
const result = { entries: [], name };
|
||||||
|
|
||||||
|
@ -3077,7 +3092,12 @@ async function sendClaudeRequest(request, response) {
|
||||||
controller.abort();
|
controller.abort();
|
||||||
});
|
});
|
||||||
|
|
||||||
const requestPrompt = convertClaudePrompt(request.body.messages, true, true);
|
let requestPrompt = convertClaudePrompt(request.body.messages, true, true);
|
||||||
|
|
||||||
|
if (request.body.assistant_prefill) {
|
||||||
|
requestPrompt += request.body.assistant_prefill;
|
||||||
|
}
|
||||||
|
|
||||||
console.log('Claude request:', requestPrompt);
|
console.log('Claude request:', requestPrompt);
|
||||||
|
|
||||||
const generateResponse = await fetch(api_url + '/complete', {
|
const generateResponse = await fetch(api_url + '/complete', {
|
||||||
|
@ -3260,6 +3280,10 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
|
||||||
message = 'API key disabled or exhausted';
|
message = 'API key disabled or exhausted';
|
||||||
console.log(message);
|
console.log(message);
|
||||||
break;
|
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 && error?.response?.data?.error?.type === 'insufficient_quota';
|
||||||
|
|
Loading…
Reference in New Issue