Merge pull request #636 from SillyTavern/dev

1.8.2
This commit is contained in:
Cohee
2023-07-05 16:11:55 +03:00
committed by GitHub
19 changed files with 760 additions and 338 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "sillytavern", "name": "sillytavern",
"version": "1.8.1", "version": "1.8.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "sillytavern", "name": "sillytavern",
"version": "1.8.1", "version": "1.8.2",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {
"@dqbd/tiktoken": "^1.0.2", "@dqbd/tiktoken": "^1.0.2",

View File

@@ -49,7 +49,7 @@
"type": "git", "type": "git",
"url": "https://github.com/SillyTavern/SillyTavern.git" "url": "https://github.com/SillyTavern/SillyTavern.git"
}, },
"version": "1.8.1", "version": "1.8.2",
"scripts": { "scripts": {
"start": "node server.js", "start": "node server.js",
"pkg": "pkg --compress Gzip --no-bytecode --public ." "pkg": "pkg --compress Gzip --no-bytecode --public ."

View File

@@ -2002,17 +2002,17 @@
</div> </div>
</div> </div>
<div class="flex1 range-block flex-container flexFlowColumn"> <div class="alignitemsflexstart flex1 range-block flex-container flexFlowColumn">
<label title="Entries can activate other entries by mentioning their keywords" class="checkbox_label"> <label title="Entries can activate other entries by mentioning their keywords" class="checkbox_label">
<input id="world_info_recursive" type="checkbox" /> <input id="world_info_recursive" type="checkbox" />
<small> <small>
Recursive scanning Recursive Scan
</small> </small>
</label> </label>
<label title="Lookup for the entry keys in the context will respect the case" class="checkbox_label"> <label title="Lookup for the entry keys in the context will respect the case" class="checkbox_label">
<input id="world_info_case_sensitive" type="checkbox" /> <input id="world_info_case_sensitive" type="checkbox" />
<small> <small>
Case-sensitive keys Case-sensitive
</small> </small>
</label> </label>
<label title="If the entry key consists of only one word, it would not be matched as part of other words" class="checkbox_label"> <label title="If the entry key consists of only one word, it would not be matched as part of other words" class="checkbox_label">
@@ -2074,6 +2074,103 @@
<div id="version_display"></div> <div id="version_display"></div>
</div> </div>
<div class="flex-container spaceEvenly"> <div class="flex-container spaceEvenly">
<div id="UI-Theme-Block" class="flex-container flexFlowColumn drawer33pWidth">
<div id="color-picker-block" class="flex-container flexFlowColumn">
<h4><span data-i18n="UI Colors">UI Colors</span></h4>
<div class="flex-container">
<toolcool-color-picker id="main-text-color-picker"></toolcool-color-picker>
<span data-i18n="Main Text">Main Text</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="italics-color-picker"></toolcool-color-picker>
<span data-i18n="Italics Text">Italics Text</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="quote-color-picker"></toolcool-color-picker>
<span data-i18n="Quote Text">Quote Text</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="shadow-color-picker"></toolcool-color-picker>
<span data-i18n="Shadow Color">Text Shadow</span>
</div>
<!-- <div class="flex-container">
<toolcool-color-picker id="fastui-bg-color-picker"></toolcool-color-picker>
<span data-i18n="FastUI BG">FastUI BG</span>
</div> -->
<div class="flex-container">
<toolcool-color-picker id="blur-tint-color-picker"></toolcool-color-picker>
<span data-i18n="Blur Tint">UI Background</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="user-mes-blur-tint-color-picker"></toolcool-color-picker>
<span data-i18n="User Message Blur Tint">User Message</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="bot-mes-blur-tint-color-picker"></toolcool-color-picker>
<span data-i18n="AI Message Blur Tint">AI Message</span>
</div>
<div id="font-blur-UIpresets-block" class="flex-container flexFlowColumn">
<div id="font-scale-block" class="range-block">
<div class="range-block-title" data-i18n="Font Scale">
Font Scale
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="font_scale" name="font_scale" min="0.8" max="1.2" step="0.05">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="font_scale" id="font_scale_counter">
select
</div>
</div>
</div>
</div>
<div id="blur-strength-block" class="range-block">
<div class="range-block-title" data-i18n="Blur Strength">
Blur Strength
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="blur_strength" name="blur_strength" min="0" max="30" step="1">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="blur_strength" id="blur_strength_counter">
select
</div>
</div>
</div>
</div>
<div id="shadow-width-block" class="range-block">
<div class="range-block-title" data-i18n="Text Shadow Width">
Text Shadow Width
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="shadow_width" name="shadow_width" min="0" max="5" step="1">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="shadow_width" id="shadow_width_counter">
select
</div>
</div>
</div>
</div>
</div>
<div id="UI-presets-block" class="flex-container flexFlowColumn">
<h4>
<span data-i18n="UI Theme Preset">UI Theme Preset</span>
</h4>
<div class="flex-container flexnowrap alignitemscenter">
<select id="themes" class="margin0 margin-r5">
</select>
<div id="ui-preset-save-button" title="Save changes to a new theme file" class="menu_button padding5 margin0">
<i class="fa-solid fa-save"></i>
</div>
</div>
</div>
</div>
</div>
<div name="UI Customization" class="flex-container drawer33pWidth"> <div name="UI Customization" class="flex-container drawer33pWidth">
<div class="ui-settings"> <div class="ui-settings">
<h4><span data-i18n="UI Customization">UI Customization</span></h4> <h4><span data-i18n="UI Customization">UI Customization</span></h4>
@@ -2183,103 +2280,7 @@
</div> </div>
</div> </div>
<div id="UI-Theme-Block" class="flex-container flexFlowColumn drawer33pWidth">
<div id="color-picker-block" class="flex-container flexFlowColumn">
<h4><span data-i18n="UI Colors">UI Colors</span></h4>
<div class="flex-container">
<toolcool-color-picker id="main-text-color-picker"></toolcool-color-picker>
<span data-i18n="Main Text">Main Text</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="italics-color-picker"></toolcool-color-picker>
<span data-i18n="Italics Text">Italics Text</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="quote-color-picker"></toolcool-color-picker>
<span data-i18n="Quote Text">Quote Text</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="shadow-color-picker"></toolcool-color-picker>
<span data-i18n="Shadow Color">Text Shadow</span>
</div>
<!-- <div class="flex-container">
<toolcool-color-picker id="fastui-bg-color-picker"></toolcool-color-picker>
<span data-i18n="FastUI BG">FastUI BG</span>
</div> -->
<div class="flex-container">
<toolcool-color-picker id="blur-tint-color-picker"></toolcool-color-picker>
<span data-i18n="Blur Tint">UI Background</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="user-mes-blur-tint-color-picker"></toolcool-color-picker>
<span data-i18n="User Message Blur Tint">User Message</span>
</div>
<div class="flex-container">
<toolcool-color-picker id="bot-mes-blur-tint-color-picker"></toolcool-color-picker>
<span data-i18n="AI Message Blur Tint">AI Message</span>
</div>
<div id="font-blur-UIpresets-block" class="flex-container flexFlowColumn">
<div id="font-scale-block" class="range-block">
<div class="range-block-title" data-i18n="Font Scale">
Font Scale
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="font_scale" name="font_scale" min="0.8" max="1.2" step="0.05">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="font_scale" id="font_scale_counter">
select
</div>
</div>
</div>
</div>
<div id="blur-strength-block" class="range-block">
<div class="range-block-title" data-i18n="Blur Strength">
Blur Strength
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="blur_strength" name="blur_strength" min="0" max="30" step="1">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="blur_strength" id="blur_strength_counter">
select
</div>
</div>
</div>
</div>
<div id="shadow-width-block" class="range-block">
<div class="range-block-title" data-i18n="Text Shadow Width">
Text Shadow Width
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="shadow_width" name="shadow_width" min="0" max="5" step="1">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="shadow_width" id="shadow_width_counter">
select
</div>
</div>
</div>
</div>
</div>
<div id="UI-presets-block" class="flex-container flexFlowColumn">
<h4>
<span data-i18n="UI Theme Preset">UI Theme Preset</span>
</h4>
<div class="flex-container flexnowrap alignitemscenter">
<select id="themes" class="margin0 margin-r5">
</select>
<div id="ui-preset-save-button" title="Save changes to a new theme file" class="menu_button padding5 margin0">
<i class="fa-solid fa-save"></i>
</div>
</div>
</div>
</div>
</div>
<div id="power-user-options-block" class="flex-container drawer33pWidth"> <div id="power-user-options-block" class="flex-container drawer33pWidth">
<div id="power-user-option-checkboxes"> <div id="power-user-option-checkboxes">
<h4 data-i18n="Power User Options">Power User Options</h4> <h4 data-i18n="Power User Options">Power User Options</h4>
@@ -3094,14 +3095,18 @@
<span data-i18n="Keywords"> <span data-i18n="Keywords">
Keywords Keywords
</span> </span>
<span>(UID:&nbsp;
<span class="world_entry_form_uid_value"></span>
)
</span>
</small> </small>
<small class="displayNone"> <small class="displayNone">
<span data-i18n="Separate with commas"> <span data-i18n="Comma separated (required)">
Separate with commas Comma separated (required)
</span> </span>
</small> </small>
</label> </label>
<textarea class="text_pole keyprimarytextpole" name="key" rows="1" placeholder="Separate with commas" maxlength="1000"></textarea> <textarea class="text_pole keyprimarytextpole" name="key" rows="1" placeholder="Comma separated (required)" maxlength="1000"></textarea>
</div> </div>
<div class="world_entry_form_control keysecondary"> <div class="world_entry_form_control keysecondary">
<label for="keysecondary"> <label for="keysecondary">
@@ -3111,12 +3116,12 @@
</span> </span>
</small> </small>
<small class="displayNone"> <small class="displayNone">
<span data-i18n="Separate with commas"> <span data-i18n="Comma seperated (ignored if empty)">
Separate with commas Comma seperated (ignored if empty)
</span> </span>
</small> </small>
</label> </label>
<textarea class="text_pole keysecondarytextpole" name="keysecondary" rows="1" placeholder="Separate with commas" maxlength="1000"></textarea> <textarea class="text_pole keysecondarytextpole" name="keysecondary" rows="1" placeholder="Comma separated (ignored if empty)" maxlength="1000"></textarea>
</div> </div>
</div> </div>
<div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
@@ -3129,6 +3134,10 @@
<small> <small>
<span data-i18n="Content"> <span data-i18n="Content">
Content Content
<span>(Tokens:&nbsp;
<span class="world_entry_form_token_counter">0</span>
)
</span>
</span> </span>
</small> </small>
<small class="displayNone"> <small class="displayNone">
@@ -3164,6 +3173,10 @@
<input type="checkbox" name="constant" /> <input type="checkbox" name="constant" />
<span data-i18n="Constant">Constant</span> <span data-i18n="Constant">Constant</span>
</label> </label>
<label class="checkbox flex-container alignitemscenter">
<input type="checkbox" name="disable" />
<span data-i18n="Disable">Disable</span>
</label>
<label class="checkbox flex-container"> <label class="checkbox flex-container">
<input type="checkbox" name="selective" /> <input type="checkbox" name="selective" />
<span data-i18n="Selective">Selective</span> <span data-i18n="Selective">Selective</span>
@@ -3177,65 +3190,57 @@
<span data-i18n="Add Memo">Add Memo</span> <span data-i18n="Add Memo">Add Memo</span>
</label> </label>
</div>
<div class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
<small>Placement</small>
<div>
<label><input type="radio" name="position" value="0">
<span data-i18n="Before Char">Before Char</span>
</label>
</div>
<div>
<label><input type="radio" name="position" value="1">
<span data-i18n="After Char">After Char</span>
</label>
</div>
<div>
<label><input type="radio" name="position" value="2">
<span data-i18n="Author's Note">Author's Note Top</span>
</label>
</div>
<div>
<label><input type="radio" name="position" value="3">
<span data-i18n="Author's Note">Author's Note Bottom</span>
</label>
</div>
</div>
<div class="container flexFlowColumn flexNoGap">
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap ">
Insertion Order
<input class="text_pole wideMax100px" type="number" name="order" placeholder="" />
</div>
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap probabilityContainer">
Probability (%)
<input class="text_pole wideMax100px" type="number" name="probability" placeholder="" min="0" max="100" />
</div>
</div>
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
<div class="world_entry_form_uid">
UID:
&nbsp;
<span class="world_entry_form_uid_value"></span>
</div>
<div class="world_entry_form_tokens">
Tokens:
&nbsp;
<span class="world_entry_form_token_counter">0</span>
</div>
</div>
<div class="wi-enter-footer-text">
<label class="checkbox flex-container alignitemscenter">
<input type="checkbox" name="disable" />
<span data-i18n="Disable">Disable</span>
</label>
<label class="checkbox flex-container alignitemscenter"> <label class="checkbox flex-container alignitemscenter">
<input type="checkbox" name="exclude_recursion" /> <input type="checkbox" name="exclude_recursion" />
<span data-i18n="Exclude from recursion">Exclude from recursion</span> <span data-i18n="Exclude from recursion">
Non-recursable
</span>
</label> </label>
</div> </div>
<!-- <div name="injectioStratBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
<label for="injectionStrat">Injection:</label>
<small>
<select name="injectionStrat">
<option value="0">Normal</option>
<option value="1">Constant</option>
<option value="2">Disabled</option>
</select>
</small>
</div> -->
<div name="PositionBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
<label for="position">Position:</label>
<small>
<select name="position">
<option value="0">Before Char Defs</option>
<option value="1">After Char Defs</option>
<option value="2">Before AN</option>
<option value="3">After AN</option>
</select>
</small>
</div>
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap ">
<label for="order">Order:</label>
<input class="text_pole wideMax100px margin0" type="number" name="order" placeholder="" />
</div>
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap probabilityContainer">
<label for="probability"></label>Probability:</label>
<input class="text_pole wideMax100px margin0" type="number" name="probability" placeholder="" min="0" max="100" />
</div>
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
</div>
<input class="menu_button delete_entry_button" type="submit" value="Delete Entry" /> <input class="menu_button delete_entry_button" type="submit" value="Delete Entry" />
</div> </div>
</div> </div>
@@ -3556,4 +3561,4 @@
</script> </script>
</body> </body>
</html> </html>

View File

@@ -89,6 +89,7 @@ import {
openai_messages_count, openai_messages_count,
getTokenCountOpenAI, getTokenCountOpenAI,
chat_completion_sources, chat_completion_sources,
getTokenizerModel,
} from "./scripts/openai.js"; } from "./scripts/openai.js";
import { import {
@@ -318,6 +319,9 @@ const system_message_types = {
BOOKMARK_BACK: "bookmark_back", BOOKMARK_BACK: "bookmark_back",
NARRATOR: "narrator", NARRATOR: "narrator",
COMMENT: "comment", COMMENT: "comment",
SLASH_COMMANDS: "slash_commands",
FORMATTING: "formatting",
HOTKEYS: "hotkeys",
}; };
const extension_prompt_types = { const extension_prompt_types = {
@@ -333,12 +337,31 @@ const system_messages = {
is_system: true, is_system: true,
is_name: true, is_name: true,
mes: [ mes: [
`Hi there! The following chat formatting commands are supported: `Hello there! Please select the help topic you would like to learn more about:
<ul> <ul>
<li><tt>{{text}}</tt> - sets a one-time behavioral bias for the AI. Resets when you send the next message. <li><a href="javascript:displayHelp('1')">Slash Commands</a> (or <tt>/help slash</tt>)</li>
</li> <li><a href="javascript:displayHelp('2')">Formatting</a> (or <tt>/help format</tt>)</li>
<li><a href="javascript:displayHelp('3')">Hotkeys</a> (or <tt>/help hotkeys</tt>)</li>
</ul> </ul>
Hotkeys/Keybinds: <br><b>Still got questions left? The <a target="_blank" href="https://docs.sillytavern.app/">Official SillyTavern Documentation Website</a> has much more information!</b>`
]
},
slash_commands: {
name: systemUserName,
force_avatar: system_avatar,
is_user: false,
is_system: true,
is_name: true,
mes: '',
},
hotkeys: {
name: systemUserName,
force_avatar: system_avatar,
is_user: false,
is_system: true,
is_name: true,
mes: [
`Hotkeys/Keybinds:
<ul> <ul>
<li><tt>Up</tt> = Edit last message in chat</li> <li><tt>Up</tt> = Edit last message in chat</li>
<li><tt>Ctrl+Up</tt> = Edit last USER message in chat</li> <li><tt>Ctrl+Up</tt> = Edit last USER message in chat</li>
@@ -350,7 +373,26 @@ const system_messages = {
<li><tt>Escape</tt> = stop AI response generation</li> <li><tt>Escape</tt> = stop AI response generation</li>
<li><tt>Ctrl+Shift+Up</tt> = Scroll to context line</li> <li><tt>Ctrl+Shift+Up</tt> = Scroll to context line</li>
<li><tt>Ctrl+Shift+Down</tt> = Scroll chat to bottom</li> <li><tt>Ctrl+Shift+Down</tt> = Scroll chat to bottom</li>
</ul>`
]
},
formatting: {
name: systemUserName,
force_avatar: system_avatar,
is_user: false,
is_system: true,
is_name: true,
mes: [
`Text formatting commands:
<ul>
<li><tt>{{text}}</tt> - sets a one-time behavioral bias for the AI. Resets when you send the next message.</li>
<li><tt>*text*</tt> - displays as <i>italics</i></li>
<li><tt>**text**</tt> - displays as <b>bold</b></li>
<li><tt>***text***</tt> - displays as <b><i>bold italics</i></b></li>
<li><tt>` + "```" + `text` + "```" + `</tt> - displays as a code block</li>
<li><tt>` + "`" + `text` + "`" + `</tt> - displays as inline code</li>
<li><tt>$$ text $$</tt> - renders a LaTeX formula (if enabled)</li>
<li><tt>$ text $</tt> - renders an AsciiMath formula (if enabled)</li>
</ul>` </ul>`
] ]
}, },
@@ -1525,9 +1567,8 @@ function sendSystemMessage(type, text, extra = {}) {
newMessage.mes = text; newMessage.mes = text;
} }
if (type == system_message_types.HELP) { if (type == system_message_types.SLASH_COMMANDS) {
newMessage.mes += getSlashCommandsHelp(); newMessage.mes = getSlashCommandsHelp();
newMessage.mes += `<br><b>Still got questions left? The <a target="_blank" href="https://docs.sillytavern.app/">Official SillyTavern Documentation Website</a> has much more information!</b>`;
} }
if (!newMessage.extra) { if (!newMessage.extra) {
@@ -1612,7 +1653,7 @@ function getPersonaDescription(storyString) {
default: default:
if (shouldWIAddPrompt) { if (shouldWIAddPrompt) {
const originalAN = extension_prompts[NOTE_MODULE_NAME].value const originalAN = extension_prompts[NOTE_MODULE_NAME].value
const ANWithDesc = persona_description_positions.TOP_AN const ANWithDesc = power_user.persona_description_position === persona_description_positions.TOP_AN
? `${power_user.persona_description}\n${originalAN}` ? `${power_user.persona_description}\n${originalAN}`
: `${originalAN}\n${power_user.persona_description}`; : `${originalAN}\n${power_user.persona_description}`;
setExtensionPrompt(NOTE_MODULE_NAME, ANWithDesc, chat_metadata[metadata_keys.position], chat_metadata[metadata_keys.depth]); setExtensionPrompt(NOTE_MODULE_NAME, ANWithDesc, chat_metadata[metadata_keys.position], chat_metadata[metadata_keys.depth]);
@@ -3076,7 +3117,7 @@ function promptItemize(itemizedPrompts, requestedMesId) {
var promptBiasTokensPercentage = ((oaiBiasTokens / (finalPromptTokens)) * 100).toFixed(2); var promptBiasTokensPercentage = ((oaiBiasTokens / (finalPromptTokens)) * 100).toFixed(2);
var worldInfoStringTokensPercentage = ((worldInfoStringTokens / (finalPromptTokens)) * 100).toFixed(2); var worldInfoStringTokensPercentage = ((worldInfoStringTokens / (finalPromptTokens)) * 100).toFixed(2);
var allAnchorsTokensPercentage = ((allAnchorsTokens / (finalPromptTokens)) * 100).toFixed(2); var allAnchorsTokensPercentage = ((allAnchorsTokens / (finalPromptTokens)) * 100).toFixed(2);
var selectedTokenizer = `tiktoken (${oai_settings.openai_model})`; var selectedTokenizer = `tiktoken (${getTokenizerModel()})`;
var oaiSystemTokens = oaiImpersonateTokens + oaiJailbreakTokens + oaiNudgeTokens + oaiStartTokens; var oaiSystemTokens = oaiImpersonateTokens + oaiJailbreakTokens + oaiNudgeTokens + oaiStartTokens;
var oaiSystemTokensPercentage = ((oaiSystemTokens / (finalPromptTokens)) * 100).toFixed(2); var oaiSystemTokensPercentage = ((oaiSystemTokens / (finalPromptTokens)) * 100).toFixed(2);
@@ -3095,7 +3136,7 @@ function promptItemize(itemizedPrompts, requestedMesId) {
callPopup( callPopup(
` `
<h3>Prompt Itemization</h3> <h3>Prompt Itemization</h3>
Tokenizer: TikToken<br> Tokenizer: ${selectedTokenizer}<br>
API Used: ${this_main_api}<br> API Used: ${this_main_api}<br>
<span class="tokenItemizingSubclass"> <span class="tokenItemizingSubclass">
Only the white numbers really matter. All numbers are estimates. Only the white numbers really matter. All numbers are estimates.
@@ -7866,8 +7907,8 @@ $(document).ready(function () {
const pinnedDrawerClicked = drawer.hasClass('pinnedOpen'); const pinnedDrawerClicked = drawer.hasClass('pinnedOpen');
if (!drawerWasOpenAlready) { //to open the drawer if (!drawerWasOpenAlready) { //to open the drawer
$('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, "swing", function () { $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, "swing", async function () {
$(this).closest('.drawer-content').removeClass('resizing'); await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
}); });
$('.openIcon').toggleClass('closedIcon openIcon'); $('.openIcon').toggleClass('closedIcon openIcon');
$('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer'); $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');
@@ -7880,16 +7921,17 @@ $(document).ready(function () {
duration: 200, duration: 200,
easing: "swing", easing: "swing",
start: function () { start: function () {
jQuery(this).css('display', 'flex'); jQuery(this).css('display', 'flex'); //flex needed to make charlist scroll
}, },
complete: function () { complete: async function () {
await delay(50);
$(this).closest('.drawer-content').removeClass('resizing'); $(this).closest('.drawer-content').removeClass('resizing');
$("#rm_print_characters_block").trigger("scroll"); $("#rm_print_characters_block").trigger("scroll");
} }
}) })
} else { } else {
$(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle(200, "swing", function () { $(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle(200, "swing", async function () {
$(this).closest('.drawer-content').removeClass('resizing'); await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
}); });
} }
@@ -7898,13 +7940,13 @@ $(document).ready(function () {
icon.toggleClass('closedIcon openIcon'); icon.toggleClass('closedIcon openIcon');
if (pinnedDrawerClicked) { if (pinnedDrawerClicked) {
$(drawer).addClass('resizing').slideToggle(200, "swing", function () { $(drawer).addClass('resizing').slideToggle(200, "swing", async function () {
$(this).removeClass('resizing'); await delay(50); $(this).removeClass('resizing');
}); });
} }
else { else {
$('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, "swing", function () { $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, "swing", async function () {
$(this).closest('.drawer-content').removeClass('resizing'); await delay(50); $(this).closest('.drawer-content').removeClass('resizing');
}); });
} }
@@ -7999,6 +8041,12 @@ $(document).ready(function () {
loadMovingUIState(); loadMovingUIState();
$(`.zoomed_avatar[forChar="${charname}"]`).css('display', 'block'); $(`.zoomed_avatar[forChar="${charname}"]`).css('display', 'block');
dragElement(newElement) dragElement(newElement)
$(`.zoomed_avatar[forChar="${charname}"] img`).on('dragstart', (e) => {
console.log('saw drag on avatar!');
e.preventDefault();
return false;
});
} }
}); });

View File

@@ -104,22 +104,6 @@ function waitForElement(querySelector, timeout) {
}); });
} }
waitForElement("#expression-image", 10000).then(function () {
dragElement(document.getElementById("expression-holder"));
dragElement(document.getElementById("floatingPrompt"));
}).catch(() => {
console.log("expression holder not loaded yet");
});
waitForElement("#floatingPrompt", 10000).then(function () {
dragElement(document.getElementById("floatingPrompt"));
}).catch(() => {
console.log("floating prompt box not loaded yet");
});
// Device detection // Device detection
export const deviceInfo = await getDeviceInfo(); export const deviceInfo = await getDeviceInfo();
@@ -474,37 +458,28 @@ function OpenNavPanels() {
// Make the DIV element draggable: // Make the DIV element draggable:
// THIRD UPDATE, prevent resize window breaks and smartly handle saving
// SECOND UPDATE AIMING FOR MUTATIONS ONLY
export function dragElement(elmnt) { export function dragElement(elmnt) {
var hasBeenDraggedByUser = false;
var isMouseDown = false;
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
var height, width, top, left, right, bottom; var height, width, top, left, right, bottom,
maxX, maxY, winHeight, winWidth,
topBarFirstX, topBarLastX, sheldWidth;
var oldTop = Number((String($(elmnt).css('top')).replace('px', '')))
var oldLeft = Number((String($(elmnt).css('left')).replace('px', '')))
var oldWidth = Number((String($(elmnt).css('width')).replace('px', '')))
var oldHeight = Number((String($(elmnt).css('width')).replace('px', '')))
var oldRight = Number((String($(elmnt).css('right')).replace('px', '')))
var oldBottom = Number((String($(elmnt).css('bottom')).replace('px', '')))
var elmntName = elmnt.attr('id'); var elmntName = elmnt.attr('id');
console.debug(`${elmntName} init state:
T: ${$(elmnt).css('top')}
L: ${$(elmnt).css('left')}
W: ${$(elmnt).css('width')}
H: ${$(elmnt).css('height')}
R: ${$(elmnt).css('right')}
B: ${$(elmnt).css('bottom')}
---`);
const elmntNameEscaped = $.escapeSelector(elmntName); const elmntNameEscaped = $.escapeSelector(elmntName);
const elmntHeader = $(`#${elmntNameEscaped}header`); const elmntHeader = $(`#${elmntNameEscaped}header`);
if (elmntHeader.length) { if (elmntHeader.length) {
elmntHeader.off('mousedown').on('mousedown', (e) => { elmntHeader.off('mousedown').on('mousedown', (e) => {
dragMouseDown(e); dragMouseDown(e);
}); });
$(elmnt).off('mousedown').on('mousedown', () => { isMouseDown = true })
} else { } else {
elmnt.off('mousedown').on('mousedown', dragMouseDown); elmnt.off('mousedown').on('mousedown', dragMouseDown);
} }
@@ -521,52 +496,87 @@ B: ${$(elmnt).css('bottom')}
console.debug('aborting mutator') console.debug('aborting mutator')
return return
} }
//console.debug(left + width, winWidth, hasBeenDraggedByUser, isMouseDown)
const style = getComputedStyle(target); const style = getComputedStyle(target); //use computed values because not all CSS are set by default
//console.log(style.top, style.left)
height = target.offsetHeight; height = target.offsetHeight;
width = target.offsetWidth; width = target.offsetWidth;
top = parseInt(style.top); top = parseInt(style.top);
left = parseInt(style.left); left = parseInt(style.left);
right = parseInt(style.right); right = parseInt(style.right);
bottom = parseInt(style.bottom); bottom = parseInt(style.bottom);
maxX = parseInt(width + left);
maxY = parseInt(height + top);
winWidth = window.innerWidth;
winHeight = window.innerHeight;
sheldWidth = parseInt($('html').css('--sheldWidth').slice(0, -2));
topBarFirstX = (winWidth - sheldWidth) / 2;
topBarLastX = topBarFirstX + sheldWidth;
//prepare an empty poweruser object for the item being altered if we don't have one already
if (!power_user.movingUIState[elmntName]) { if (!power_user.movingUIState[elmntName]) {
console.debug(`adding config property for ${elmntName}`) console.debug(`adding config property for ${elmntName}`)
power_user.movingUIState[elmntName] = {}; power_user.movingUIState[elmntName] = {};
} }
power_user.movingUIState[elmntName].top = top; //only record position changes if caused by a user click-drag
power_user.movingUIState[elmntName].left = left; if (hasBeenDraggedByUser && isMouseDown) {
power_user.movingUIState[elmntName].top = top;
if (!isNaN(oldWidth) power_user.movingUIState[elmntName].left = left;
&& !isNaN(oldHeight) power_user.movingUIState[elmntName].right = right;
&& (oldHeight !== height || oldWidth !== width)) { power_user.movingUIState[elmntName].bottom = bottom;
power_user.movingUIState[elmntName].width = width;
power_user.movingUIState[elmntName].height = height;
} else {
console.debug('skipping W/H setting')
}
power_user.movingUIState[elmntName].right = right;
power_user.movingUIState[elmntName].bottom = bottom;
if (!isNaN(oldTop) && !isNaN(oldLeft) && (oldTop !== top || oldLeft !== left)) {
console.debug('unsetting margin due to custom position')
console.debug(`${elmntName}:
T: ${oldTop}>>${top}
L: ${oldLeft}>> ${left}
H: ${oldHeight} >> ${height}
W: ${oldWidth}>> ${width}
R: ${oldRight} >> ${right}
B: ${oldBottom}>> ${bottom}
---`)
power_user.movingUIState[elmntName].margin = 'unset'; power_user.movingUIState[elmntName].margin = 'unset';
} else {
console.debug('skipped unsetting margins')
//console.debug(oldTop, top, oldLeft, left)
} }
saveSettingsDebounced();
//handle resizing
if (!hasBeenDraggedByUser && isMouseDown) {
console.log('saw resize, NOT header drag')
//set css to prevent weird resize behavior (does not save)
elmnt.css('left', left)
elmnt.css('top', top)
//prevent resizing offscreen
if (top + elmnt.height() >= winHeight) {
elmnt.css('height', winHeight - top - 1 + "px");
}
if (left + elmnt.width() >= winWidth) {
elmnt.css('width', winWidth - left - 1 + "px");
}
//prevent resizing into the top bar
if (top <= 40 && maxX > topBarFirstX) {
elmnt.css('width', width - 1 + "px");
}
//set a listener for mouseup to save new width/height
elmnt.off('mouseup').on('mouseup', () => {
console.debug(`Saving ${elmntName} Height/Width`)
power_user.movingUIState[elmntName].width = width;
power_user.movingUIState[elmntName].height = height;
saveSettingsDebounced();
})
}
//handle dragging hit detection
if (hasBeenDraggedByUser && isMouseDown) {
//prevent dragging offscreen
if (top <= 0) {
elmnt.css('top', '0px');
} else if (maxY >= winHeight) {
elmnt.css('top', winHeight - maxY + top - 1 + "px");
}
if (left <= 0) {
elmnt.css('left', '0px');
} else if (maxX >= winWidth) {
elmnt.css('left', winWidth - maxX + left - 1 + "px");
}
//prevent underlap with topbar div
if (top < 40 && (maxX > topBarFirstX && maxX < topBarLastX || left < topBarLastX && left > topBarFirstX)) {
console.log('saw topbar hit')
elmnt.css('top', '42px');
}
}
// Check if the element header exists and set the listener on the grabber // Check if the element header exists and set the listener on the grabber
if (elmntHeader.length) { if (elmntHeader.length) {
@@ -584,6 +594,7 @@ B: ${oldBottom}>> ${bottom}
function dragMouseDown(e) { function dragMouseDown(e) {
if (e) { if (e) {
hasBeenDraggedByUser = true;
e.preventDefault(); e.preventDefault();
pos3 = e.clientX; //mouse X at click pos3 = e.clientX; //mouse X at click
pos4 = e.clientY; //mouse Y at click pos4 = e.clientY; //mouse Y at click
@@ -593,76 +604,60 @@ B: ${oldBottom}>> ${bottom}
} }
function elementDrag(e) { function elementDrag(e) {
$("body").css("overflow", "hidden");
if (!power_user.movingUIState[elmntName]) { if (!power_user.movingUIState[elmntName]) {
power_user.movingUIState[elmntName] = {}; power_user.movingUIState[elmntName] = {};
} }
let winWidth = window.innerWidth;
let winHeight = window.innerHeight;
let sheldWidth = parseInt($('html').css('--sheldWidth').slice(0, -2));
let topBarFirstX = (winWidth - sheldWidth) / 2;
let topBarLastX = topBarFirstX + sheldWidth;
let maxX = (width + left);
let maxY = (height + top);
e = e || window.event; e = e || window.event;
e.preventDefault(); e.preventDefault();
pos1 = pos3 - e.clientX; //X change amt pos1 = pos3 - e.clientX; //X change amt (-1 or 1)
pos2 = pos4 - e.clientY; //Y change amt pos2 = pos4 - e.clientY; //Y change amt (-1 or 1)
pos3 = e.clientX; //new mouse X pos3 = e.clientX; //new mouse X
pos4 = e.clientY; //new mouse Y pos4 = e.clientY; //new mouse Y
elmnt.attr('data-dragged', 'true'); elmnt.attr('data-dragged', 'true');
if (elmnt.offset().top < 40) { //first set css to computed values to avoid CSS NaN results from 'auto', etc
if (maxX > topBarFirstX && maxX < topBarLastX) { elmnt.css('left', (elmnt.offset().left) + "px");
elmnt.css('top', '42px'); elmnt.css("top", (elmnt.offset().top) + "px");
}
if (elmnt.offset().left < topBarLastX && elmnt.offset().left > topBarFirstX) { //then update element position styles to account for drag changes
elmnt.css('top', '42px'); elmnt.css('margin', 'unset');
}
}
if (elmnt.offset().top - pos2 <= 0) {
elmnt.css('top', '0px');
}
if (elmnt.offset().left - pos1 <= 0) {
elmnt.css('left', '0px');
}
if (maxX >= winWidth) {
elmnt.css('left', elmnt.offset().left - 10 + "px");
}
if (maxY >= winHeight) {
elmnt.css('top', elmnt.offset().top - 10 + "px");
if (elmnt.offset().top - pos2 <= 40) {
elmnt.css('top', '20px');
}
}
elmnt.css('left', (elmnt.offset().left - pos1) + "px"); elmnt.css('left', (elmnt.offset().left - pos1) + "px");
elmnt.css("top", (elmnt.offset().top - pos2) + "px"); elmnt.css("top", (elmnt.offset().top - pos2) + "px");
elmnt.css('margin', 'unset'); elmnt.css("right", ((winWidth - maxX) + "px"));
elmnt.css("bottom", ((winHeight - maxY) + "px"));
/* // Height/Width here are for visuals only, and are not saved to settings
console.log(` // required because some divs do hot have a set width/height..
winWidth: ${winWidth}, winHeight: ${winHeight} // and will defaults to shrink to min value of 100px set in CSS file
sheldWidth: ${sheldWidth} elmnt.css('height', height + "px")
X: ${$(elmnt).css('left')} elmnt.css('width', width + "px")
Y: ${$(elmnt).css('top')}
MaxX: ${maxX}, MaxY: ${maxY} /* console.log(`
Topbar 1st X: ${((winWidth - sheldWidth) / 2)} winWidth: ${winWidth}, winHeight: ${winHeight}
TopBar lastX: ${((winWidth - sheldWidth) / 2) + sheldWidth} sheldWidth: ${sheldWidth}
`); X: ${$(elmnt).css('left')}
*/ Y: ${$(elmnt).css('top')}
MaxX: ${maxX}, MaxY: ${maxY}
Topbar 1st X: ${((winWidth - sheldWidth) / 2)}
TopBar lastX: ${((winWidth - sheldWidth) / 2) + sheldWidth}
`); */
return
} }
function closeDragElement() { function closeDragElement() {
console.debug('drag finished') console.debug('drag finished')
hasBeenDraggedByUser = false;
isMouseDown = false;
$(document).off('mouseup', closeDragElement); $(document).off('mouseup', closeDragElement);
$(document).off('mousemove', elementDrag); $(document).off('mousemove', elementDrag);
$("body").css("overflow", ""); $("body").css("overflow", "");
// Clear the "data-dragged" attribute // Clear the "data-dragged" attribute
elmnt.attr('data-dragged', 'false'); elmnt.attr('data-dragged', 'false');
console.debug(`Saving ${elmntName} UI position`)
saveSettingsDebounced();
} }
} }
@@ -677,7 +672,6 @@ export async function initMovingUI() {
await delay(1000) await delay(1000)
console.debug('loading AN draggable function') console.debug('loading AN draggable function')
dragElement($("#floatingPrompt")) dragElement($("#floatingPrompt"))
} }
} }

View File

@@ -1,7 +1,7 @@
import { callPopup, eventSource, event_types, getRequestHeaders, saveSettingsDebounced } from "../../../script.js"; import { callPopup, eventSource, event_types, getRequestHeaders, saveSettingsDebounced } from "../../../script.js";
import { dragElement, isMobile } from "../../RossAscends-mods.js"; import { dragElement, isMobile } from "../../RossAscends-mods.js";
import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch } from "../../extensions.js"; import { getContext, getApiUrl, modules, extension_settings, ModuleWorkerWrapper, doExtrasFetch } from "../../extensions.js";
import { power_user } from "../../power-user.js"; import { loadMovingUIState, power_user } from "../../power-user.js";
import { onlyUnique, debounce, getCharaFilename } from "../../utils.js"; import { onlyUnique, debounce, getCharaFilename } from "../../utils.js";
export { MODULE_NAME }; export { MODULE_NAME };
@@ -182,20 +182,20 @@ async function visualNovelUpdateLayers(container) {
const group = context.groups.find(x => x.id == context.groupId); const group = context.groups.find(x => x.id == context.groupId);
const recentMessages = context.chat.map(x => x.original_avatar).filter(x => x).reverse().filter(onlyUnique); const recentMessages = context.chat.map(x => x.original_avatar).filter(x => x).reverse().filter(onlyUnique);
const filteredMembers = group.members.filter(x => !group.disabled_members.includes(x)); const filteredMembers = group.members.filter(x => !group.disabled_members.includes(x));
const layerIndices = filteredMembers.slice().sort((a, b) => { const layerIndices = filteredMembers.slice().sort((a, b) => {
const aRecentIndex = recentMessages.indexOf(a); const aRecentIndex = recentMessages.indexOf(a);
const bRecentIndex = recentMessages.indexOf(b); const bRecentIndex = recentMessages.indexOf(b);
const aFilteredIndex = filteredMembers.indexOf(a); const aFilteredIndex = filteredMembers.indexOf(a);
const bFilteredIndex = filteredMembers.indexOf(b); const bFilteredIndex = filteredMembers.indexOf(b);
if (aRecentIndex !== -1 && bRecentIndex !== -1) { if (aRecentIndex !== -1 && bRecentIndex !== -1) {
return bRecentIndex - aRecentIndex; return bRecentIndex - aRecentIndex;
} else if (aRecentIndex !== -1) { } else if (aRecentIndex !== -1) {
return 1; return 1;
} else if (bRecentIndex !== -1) { } else if (bRecentIndex !== -1) {
return -1; return -1;
} else { } else {
return aFilteredIndex - bFilteredIndex; return aFilteredIndex - bFilteredIndex;
} }
}); });
@@ -566,7 +566,7 @@ function getListItem(item, imageSrc, textClass) {
<span class="expression_list_title ${textClass}">${item}</span> <span class="expression_list_title ${textClass}">${item}</span>
<img class="expression_list_image" src="${imageSrc}" /> <img class="expression_list_image" src="${imageSrc}" />
</div> </div>
`; `;
} }
async function getSpritesList(name) { async function getSpritesList(name) {
@@ -905,6 +905,7 @@ function setExpressionOverrideHtml(forceClear = false) {
</div> </div>
</div>`; </div>`;
$('body').append(html); $('body').append(html);
loadMovingUIState();
} }
function addVisualNovelMode() { function addVisualNovelMode() {
const html = ` const html = `
@@ -959,6 +960,10 @@ function setExpressionOverrideHtml(forceClear = false) {
$('#expression_upload_pack_button').on('click', onClickExpressionUploadPackButton); $('#expression_upload_pack_button').on('click', onClickExpressionUploadPackButton);
$('#expressions_show_default').prop('checked', extension_settings.expressions.showDefault).trigger('input'); $('#expressions_show_default').prop('checked', extension_settings.expressions.showDefault).trigger('input');
$('#expression_override_cleanup_button').on('click', onClickExpressionOverrideRemoveAllButton); $('#expression_override_cleanup_button').on('click', onClickExpressionOverrideRemoveAllButton);
$(document).on('dragstart', '.expression', (e) => {
e.preventDefault()
return false
})
$(document).on('click', '.expression_list_item', onClickExpressionImage); $(document).on('click', '.expression_list_item', onClickExpressionImage);
$(document).on('click', '.expression_list_upload', onClickExpressionUpload); $(document).on('click', '.expression_list_upload', onClickExpressionUpload);
$(document).on('click', '.expression_list_delete', onClickExpressionDelete); $(document).on('click', '.expression_list_delete', onClickExpressionDelete);
@@ -973,6 +978,7 @@ function setExpressionOverrideHtml(forceClear = false) {
const updateFunction = wrapper.update.bind(wrapper); const updateFunction = wrapper.update.bind(wrapper);
setInterval(updateFunction, UPDATE_INTERVAL); setInterval(updateFunction, UPDATE_INTERVAL);
moduleWorker(); moduleWorker();
dragElement($("#expression-holder"))
eventSource.on(event_types.CHAT_CHANGED, () => { eventSource.on(event_types.CHAT_CHANGED, () => {
setExpressionOverrideHtml(); setExpressionOverrideHtml();

View File

@@ -31,6 +31,21 @@
object-fit: cover; object-fit: cover;
}*/ }*/
/* .expression-holder {
min-width: 100px;
min-height: 100px;
max-height: 90vh;
max-width: 90vh;
width: calc((100vw - var(--sheldWidth)) /2);
position: absolute;
padding: 0;
filter: drop-shadow(2px 2px 2px #51515199);
z-index: 29;
overflow: hidden;
display: none;
bottom: 0;
} */
.expression-holder { .expression-holder {
min-width: 100px; min-width: 100px;
min-height: 100px; min-height: 100px;
@@ -38,7 +53,7 @@
max-width: 90vh; max-width: 90vh;
width: calc((100vw - var(--sheldWidth)) /2); width: calc((100vw - var(--sheldWidth)) /2);
position: absolute; position: absolute;
bottom: 1px; bottom: 0;
padding: 0; padding: 0;
filter: drop-shadow(2px 2px 2px #51515199); filter: drop-shadow(2px 2px 2px #51515199);
z-index: 2; z-index: 2;
@@ -166,4 +181,4 @@ img.expression.default {
div.expression { div.expression {
display: none; display: none;
} }
} }

View File

@@ -505,8 +505,8 @@ function doAutoAdjust(chat, maxContext) {
// Round up to nearest 10 // Round up to nearest 10
const contextMessagesRounded = Math.ceil(contextMessages / 10) * 10; const contextMessagesRounded = Math.ceil(contextMessages / 10) * 10;
console.debug('CHROMADB: Estimated context messages (rounded): %o', contextMessagesRounded); console.debug('CHROMADB: Estimated context messages (rounded): %o', contextMessagesRounded);
// Messages to keep (proportional, rounded to nearest 5, minimum 10, maximum 500) // Messages to keep (proportional, rounded to nearest 5, minimum 5, maximum 500)
const messagesToKeep = Math.min(defaultSettings.keep_context_max, Math.max(10, Math.ceil(contextMessagesRounded * extension_settings.chromadb.keep_context_proportion / 5) * 5)); const messagesToKeep = Math.min(defaultSettings.keep_context_max, Math.max(5, Math.floor(contextMessagesRounded * extension_settings.chromadb.keep_context_proportion / 5) * 5));
console.debug('CHROMADB: Estimated messages to keep: %o', messagesToKeep); console.debug('CHROMADB: Estimated messages to keep: %o', messagesToKeep);
// Messages to query (rounded, maximum 500) // Messages to query (rounded, maximum 500)
const messagesToQuery = Math.min(defaultSettings.n_results_max, contextMessagesRounded - messagesToKeep); const messagesToQuery = Math.min(defaultSettings.n_results_max, contextMessagesRounded - messagesToKeep);

View File

@@ -1,10 +1,10 @@
import { callPopup, main_api } from "../../../script.js"; import { callPopup, main_api } from "../../../script.js";
import { getContext } from "../../extensions.js"; import { getContext } from "../../extensions.js";
import { oai_settings } from "../../openai.js"; import { getTokenizerModel } from "../../openai.js";
async function doTokenCounter() { async function doTokenCounter() {
const selectedTokenizer = main_api == 'openai' const selectedTokenizer = main_api == 'openai'
? `tiktoken (${oai_settings.openai_model})` ? `tiktoken (${getTokenizerModel()})`
: $("#tokenizer").find(':selected').text(); : $("#tokenizer").find(':selected').text();
const html = ` const html = `
<div class="wide100p"> <div class="wide100p">

View File

@@ -937,7 +937,7 @@ function countTokens(messages, full = false) {
return token_count; return token_count;
} }
function getTokenizerModel() { export function getTokenizerModel() {
// OpenAI models always provide their own tokenizer // OpenAI models always provide their own tokenizer
if (oai_settings.chat_completion_source == chat_completion_sources.OPENAI) { if (oai_settings.chat_completion_source == chat_completion_sources.OPENAI) {
return oai_settings.openai_model; return oai_settings.openai_model;

View File

@@ -27,7 +27,7 @@ import {
import { registerSlashCommand } from "./slash-commands.js"; import { registerSlashCommand } from "./slash-commands.js";
import { delay } from "./utils.js"; import { delay, debounce } from "./utils.js";
export { export {
loadPowerUserSettings, loadPowerUserSettings,
@@ -983,7 +983,7 @@ async function saveTheme() {
} }
} }
function resetMovablePanels() { async function resetMovablePanels(type) {
const panelIds = [ const panelIds = [
'sheld', 'sheld',
'left-nav-panel', 'left-nav-panel',
@@ -999,28 +999,38 @@ function resetMovablePanels() {
const panel = document.getElementById(id); const panel = document.getElementById(id);
if (panel) { if (panel) {
$(panel).addClass('resizing');
panelStyles.forEach((style) => { panelStyles.forEach((style) => {
panel.style[style] = ''; panel.style[style] = '';
}); });
} }
}); });
const zoomedAvatar = document.querySelector('.zoomed_avatar'); const zoomedAvatars = document.querySelectorAll('.zoomed_avatar');
if (zoomedAvatar) { if (zoomedAvatars.length > 0) {
panelStyles.forEach((style) => { zoomedAvatars.forEach((avatar) => {
zoomedAvatar.style[style] = ''; avatar.classList.add('resizing');
panelStyles.forEach((style) => {
avatar.style[style] = '';
});
}); });
} }
$('[data-dragged="true"]').removeAttr('data-dragged'); $('[data-dragged="true"]').removeAttr('data-dragged');
await delay(50)
power_user.movingUIState = {}; power_user.movingUIState = {};
saveSettingsDebounced(); saveSettingsDebounced();
eventSource.emit(event_types.MOVABLE_PANELS_RESET); eventSource.emit(event_types.MOVABLE_PANELS_RESET);
eventSource.once(event_types.SETTINGS_UPDATED, () => { eventSource.once(event_types.SETTINGS_UPDATED, () => {
toastr.success('Panel positions reset'); $(".resizing").removeClass('resizing');
if (type === 'resize') {
toastr.warning('Panel positions reset due to zoom/resize');
} else {
toastr.success('Panel positions reset');
}
}); });
} }
function doNewChat() { function doNewChat() {
@@ -1113,7 +1123,252 @@ function doResetPanels() {
$("#movingUIreset").trigger('click'); $("#movingUIreset").trigger('click');
} }
function setAvgBG() {
const bgimg = new Image();
bgimg.src = $('#bg1')
.css('background-image')
.replace(/^url\(['"]?/, '')
.replace(/['"]?\)$/, '');
/* const charAvatar = new Image()
charAvatar.src = $("#avatar_load_preview")
.attr('src')
.replace(/^url\(['"]?/, '')
.replace(/['"]?\)$/, '');
const userAvatar = new Image()
userAvatar.src = $("#user_avatar_block .avatar.selected img")
.attr('src')
.replace(/^url\(['"]?/, '')
.replace(/['"]?\)$/, ''); */
bgimg.onload = function () {
var rgb = getAverageRGB(bgimg);
//console.log(`average color of the bg is:`)
//console.log(rgb);
$("#blur-tint-color-picker").attr('color', 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')');
const backgroundColorString = $("#blur-tint-color-picker").attr('color')
.replace('rgba', '')
.replace('rgb', '')
.replace('(', '[')
.replace(')', ']'); //[50, 120, 200, 1]; // Example background color
const backgroundColorArray = JSON.parse(backgroundColorString) //[200, 200, 200, 1]
console.log(backgroundColorArray)
$("#main-text-color-picker").attr('color', getReadableTextColor(backgroundColorArray));
console.log($("#main-text-color-picker").attr('color')); // Output: 'rgba(0, 47, 126, 1)'
}
/* charAvatar.onload = function () {
var rgb = getAverageRGB(charAvatar);
//console.log(`average color of the AI avatar is:`);
//console.log(rgb);
$("#bot-mes-blur-tint-color-picker").attr('color', 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')');
}
userAvatar.onload = function () {
var rgb = getAverageRGB(userAvatar);
//console.log(`average color of the user avatar is:`);
//console.log(rgb);
$("#user-mes-blur-tint-color-picker").attr('color', 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')');
} */
function getAverageRGB(imgEl) {
var blockSize = 5, // only visit every 5 pixels
defaultRGB = { r: 0, g: 0, b: 0 }, // for non-supporting envs
canvas = document.createElement('canvas'),
context = canvas.getContext && canvas.getContext('2d'),
data, width, height,
i = -4,
length,
rgb = { r: 0, g: 0, b: 0 },
count = 0;
if (!context) {
return defaultRGB;
}
height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;
context.drawImage(imgEl, 0, 0);
try {
data = context.getImageData(0, 0, width, height);
} catch (e) {
/* security error, img on diff domain */alert('x');
return defaultRGB;
}
length = data.data.length;
while ((i += blockSize * 4) < length) {
++count;
rgb.r += data.data[i];
rgb.g += data.data[i + 1];
rgb.b += data.data[i + 2];
}
// ~~ used to floor values
rgb.r = ~~(rgb.r / count);
rgb.g = ~~(rgb.g / count);
rgb.b = ~~(rgb.b / count);
return rgb;
}
function hslToRgb(h, s, l) {
const hueToRgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
if (s === 0) {
return [l, l, l];
}
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
const r = hueToRgb(p, q, h + 1 / 3);
const g = hueToRgb(p, q, h);
const b = hueToRgb(p, q, h - 1 / 3);
return [r * 255, g * 255, b * 255];
}
function rgbToLuminance(r, g, b) {
console.log(r, g, b)
const gammaCorrect = (color) => {
return color <= 0.03928
? color / 12.92
: Math.pow((color + 0.055) / 1.055, 2.4);
};
const rsRGB = r / 255;
const gsRGB = g / 255;
const bsRGB = b / 255;
const rLuminance = gammaCorrect(rsRGB).toFixed(2);
const gLuminance = gammaCorrect(gsRGB).toFixed(2);
const bLuminance = gammaCorrect(bsRGB).toFixed(2);
console.log(`rLum ${rLuminance}, gLum ${gLuminance}, bLum ${bLuminance}`)
return 0.2126 * rLuminance + 0.7152 * gLuminance + 0.0722 * bLuminance;
}
//this version keeps BG and main text in same hue
/* function getReadableTextColor(rgb) {
const [r, g, b] = rgb;
// Convert RGB to HSL
const rgbToHsl = (r, g, b) => {
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const d = max - min;
const l = (max + min) / 2;
if (d === 0) return [0, 0, l];
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
const h = (() => {
switch (max) {
case r:
return (g - b) / d + (g < b ? 6 : 0);
case g:
return (b - r) / d + 2;
case b:
return (r - g) / d + 4;
}
})() / 6;
return [h, s, l];
};
const [h, s, l] = rgbToHsl(r / 255, g / 255, b / 255);
// Calculate appropriate text color based on background color
const targetLuminance = l > 0.5 ? 0.2 : 0.8;
const targetSaturation = s > 0.5 ? s - 0.2 : s + 0.2;
const [rNew, gNew, bNew] = hslToRgb(h, targetSaturation, targetLuminance);
// Return the text color in RGBA format
return `rgba(${rNew.toFixed(0)}, ${gNew.toFixed(0)}, ${bNew.toFixed(0)}, 1)`;
}*/
//this version makes main text complimentary color to BG color
function getReadableTextColor(rgb) {
const [r, g, b] = rgb;
// Convert RGB to HSL
const rgbToHsl = (r, g, b) => {
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const d = max - min;
const l = (max + min) / 2;
if (d === 0) return [0, 0, l];
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
const h = (() => {
switch (max) {
case r:
return (g - b) / d + (g < b ? 6 : 0);
case g:
return (b - r) / d + 2;
case b:
return (r - g) / d + 4;
}
})() / 6;
return [h, s, l];
};
const [h, s, l] = rgbToHsl(r / 255, g / 255, b / 255);
// Calculate complementary color based on background color
const complementaryHue = (h + 0.5) % 1;
const complementarySaturation = s > 0.5 ? s - 0.6 : s + 0.6;
const complementaryLuminance = l > 0.5 ? 0.2 : 0.8;
// Convert complementary color back to RGB
const [rNew, gNew, bNew] = hslToRgb(complementaryHue, complementarySaturation, complementaryLuminance);
// Return the text color in RGBA format
return `rgba(${rNew.toFixed(0)}, ${gNew.toFixed(0)}, ${bNew.toFixed(0)}, 1)`;
}
}
$(document).ready(() => { $(document).ready(() => {
$(window).on('resize', async () => {
if (isMobile()) {
return
}
//console.log('Window resized!');
const zoomLevel = Number(window.devicePixelRatio).toFixed(2);
const winWidth = window.innerWidth;
const winHeight = window.innerHeight;
console.debug(`Zoom: ${zoomLevel}, X:${winWidth}, Y:${winHeight}`);
if (Object.keys(power_user.movingUIState).length > 0) {
resetMovablePanels('resize');
}
// Adjust layout and styling here
});
// Settings that go to settings.json // Settings that go to settings.json
$("#collapse-newlines-checkbox").change(function () { $("#collapse-newlines-checkbox").change(function () {
power_user.collapse_newlines = !!$(this).prop("checked"); power_user.collapse_newlines = !!$(this).prop("checked");
@@ -1194,7 +1449,7 @@ $(document).ready(() => {
reloadMarkdownProcessor(power_user.render_formulas); reloadMarkdownProcessor(power_user.render_formulas);
}); });
$("#start_reply_with").on('input', function() { $("#start_reply_with").on('input', function () {
power_user.user_prompt_bias = $(this).val(); power_user.user_prompt_bias = $(this).val();
saveSettingsDebounced(); saveSettingsDebounced();
}); });
@@ -1545,4 +1800,5 @@ $(document).ready(() => {
registerSlashCommand('delmode', doDelMode, ['del'], '<span class="monospace">(optional number)</span> enter message deletion mode, and auto-deletes N messages if numeric argument is provided', true, true); registerSlashCommand('delmode', doDelMode, ['del'], '<span class="monospace">(optional number)</span> enter message deletion mode, and auto-deletes N messages if numeric argument is provided', true, true);
registerSlashCommand('cut', doMesCut, [], ' <span class="monospace">(requred number)</span> cuts the specified message from the chat', true, true); registerSlashCommand('cut', doMesCut, [], ' <span class="monospace">(requred number)</span> cuts the specified message from the chat', true, true);
registerSlashCommand('resetpanels', doResetPanels, ['resetui'], ' resets UI panels to original state.', true, true); registerSlashCommand('resetpanels', doResetPanels, ['resetui'], ' resets UI panels to original state.', true, true);
registerSlashCommand('bgcol', setAvgBG, [], ' WIP test of auto-bg avg coloring', true, true);
}); });

View File

@@ -17,10 +17,11 @@ import {
comment_avatar, comment_avatar,
system_avatar, system_avatar,
system_message_types, system_message_types,
name1, replaceCurrentChat,
saveSettings, setCharacterId,
} from "../script.js"; } from "../script.js";
import { humanizedDateTime } from "./RossAscends-mods.js"; import { humanizedDateTime } from "./RossAscends-mods.js";
import { resetSelectedGroup } from "./group-chats.js";
import { chat_styles, power_user } from "./power-user.js"; import { chat_styles, power_user } from "./power-user.js";
export { export {
executeSlashCommands, executeSlashCommands,
@@ -111,11 +112,53 @@ parser.addCommand('single', setStoryModeCallback, ['story'], ' sets the mess
parser.addCommand('bubble', setBubbleModeCallback, ['bubbles'], ' sets the message style to bubble chat mode', true, true); parser.addCommand('bubble', setBubbleModeCallback, ['bubbles'], ' sets the message style to bubble chat mode', true, true);
parser.addCommand('flat', setFlatModeCallback, ['default'], ' sets the message style to flat chat mode', true, true); parser.addCommand('flat', setFlatModeCallback, ['default'], ' sets the message style to flat chat mode', true, true);
parser.addCommand('continue', continueChatCallback, ['cont'], ' continues the last message in the chat', true, true); parser.addCommand('continue', continueChatCallback, ['cont'], ' continues the last message in the chat', true, true);
parser.addCommand('go', goToCharacterCallback, ['char'], '<span class="monospace">(name)</span> opens up a chat with the character by its name', true, true);
const NARRATOR_NAME_KEY = 'narrator_name'; const NARRATOR_NAME_KEY = 'narrator_name';
const NARRATOR_NAME_DEFAULT = 'System'; const NARRATOR_NAME_DEFAULT = 'System';
const COMMENT_NAME_DEFAULT = 'Note'; const COMMENT_NAME_DEFAULT = 'Note';
function findCharacterIndex(name) {
const matchTypes = [
(a, b) => a === b,
(a, b) => a.startsWith(b),
(a, b) => a.includes(b),
];
for (const matchType of matchTypes) {
const index = characters.findIndex(x => matchType(x.name.toLowerCase(), name.toLowerCase()));
if (index !== -1) {
return index;
}
}
return -1;
}
function goToCharacterCallback(_, name) {
if (!name) {
console.warn('WARN: No character name provided for /go command');
return;
}
name = name.trim();
const characterIndex = findCharacterIndex(name);
if (characterIndex !== -1) {
openChat(characterIndex);
} else {
console.warn(`No matches found for name "${name}"`);
}
}
function openChat(id) {
resetSelectedGroup();
setCharacterId(id);
setTimeout(() => {
replaceCurrentChat();
}, 1);
}
function continueChatCallback() { function continueChatCallback() {
// Prevent infinite recursion // Prevent infinite recursion
$('#send_textarea').val(''); $('#send_textarea').val('');
@@ -276,10 +319,28 @@ async function sendCommentMessage(_, text) {
saveChatConditional(); saveChatConditional();
} }
function helpCommandCallback() { function helpCommandCallback(_, type) {
sendSystemMessage(system_message_types.HELP); switch (type?.trim()) {
case 'slash':
case '1':
sendSystemMessage(system_message_types.SLASH_COMMANDS);
break;
case 'format':
case '2':
sendSystemMessage(system_message_types.FORMATTING);
break;
case 'hotkeys':
case '3':
sendSystemMessage(system_message_types.HOTKEYS);
break;
default:
sendSystemMessage(system_message_types.HELP);
break;
}
} }
window['displayHelp'] = (page) => helpCommandCallback(null, page);
function setBackgroundCallback(_, bg) { function setBackgroundCallback(_, bg) {
if (!bg) { if (!bg) {
return; return;

View File

@@ -262,6 +262,7 @@ async function importTags(imported_char) {
}; };
saveSettingsDebounced(); saveSettingsDebounced();
await getCharacters(); await getCharacters();
await getSettings();
printTagFilters(tag_filter_types.character); printTagFilters(tag_filter_types.character);
printTagFilters(tag_filter_types.group_member); printTagFilters(tag_filter_types.group_member);

View File

@@ -408,7 +408,8 @@ function appendWorldEntry(name, data, entry) {
}); });
commentInput.val(entry.comment).trigger("input"); commentInput.val(entry.comment).trigger("input");
commentToggle.prop("checked", entry.addMemo).trigger("input"); commentToggle.prop("checked", true /* entry.addMemo */).trigger("input");
commentToggle.parent().hide()
// content // content
const countTokensDebounced = debounce(function (that, value) { const countTokensDebounced = debounce(function (that, value) {
@@ -464,7 +465,8 @@ function appendWorldEntry(name, data, entry) {
value ? keysecondary.show() : keysecondary.hide(); value ? keysecondary.show() : keysecondary.hide();
}); });
selectiveInput.prop("checked", entry.selective).trigger("input"); selectiveInput.prop("checked", true /* entry.selective */).trigger("input");
selectiveInput.parent().hide();
// constant // constant
@@ -537,7 +539,7 @@ function appendWorldEntry(name, data, entry) {
value ? probabilityContainer.show() : probabilityContainer.hide(); value ? probabilityContainer.show() : probabilityContainer.hide();
if (value && data.entries[uid].probability === null) { if (value && data.entries[uid].probability === null) {
data.entries[uid].probability = 50; data.entries[uid].probability = 100;
} }
if (!value) { if (!value) {
@@ -546,14 +548,15 @@ function appendWorldEntry(name, data, entry) {
probabilityInput.val(data.entries[uid].probability).trigger("input"); probabilityInput.val(data.entries[uid].probability).trigger("input");
}); });
probabilityToggle.prop("checked", entry.useProbability).trigger("input"); probabilityToggle.prop("checked", true /* entry.useProbability */).trigger("input");
probabilityToggle.parent().hide();
// position // position
if (entry.position === undefined) { if (entry.position === undefined) {
entry.position = 0; entry.position = 0;
} }
const positionInput = template.find('input[name="position"]'); const positionInput = template.find('select[name="position"]');
positionInput.data("uid", entry.uid); positionInput.data("uid", entry.uid);
positionInput.on("input", function () { positionInput.on("input", function () {
const uid = $(this).data("uid"); const uid = $(this).data("uid");
@@ -565,9 +568,10 @@ function appendWorldEntry(name, data, entry) {
setOriginalDataValue(data, uid, "extensions.position", data.entries[uid].position); setOriginalDataValue(data, uid, "extensions.position", data.entries[uid].position);
saveWorldInfo(name, data); saveWorldInfo(name, data);
}); });
template template
.find(`input[name="position"][value=${entry.position}]`) .find(`select[name="position"] option[value=${entry.position}]`)
.prop("checked", true) .prop("selected", true)
.trigger("input"); .trigger("input");
// display uid // display uid

View File

@@ -293,6 +293,7 @@ code {
padding: 0 3px; padding: 0 3px;
/* max-width: calc(100svw - 95px); */ /* max-width: calc(100svw - 95px); */
line-height: var(--mainFontSize); line-height: var(--mainFontSize);
color: var(--white70a);
} }
@@ -745,7 +746,7 @@ hr {
min-width: 50px !important; min-width: 50px !important;
} }
.hotswapAvatar.group_select .avatar img { .hotswapAvatar.group_select .avatar.avatar_collage img {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
@@ -2148,7 +2149,7 @@ grammarly-extension {
} }
.delete_entry_button { .delete_entry_button {
align-self: center; height: min-content;
} }
.world_entry_form_control.world_entry_form_horizontal { .world_entry_form_control.world_entry_form_horizontal {
@@ -3925,11 +3926,13 @@ label[for="extensions_autoconnect"] {
z-index: 9999 !important; z-index: 9999 !important;
} }
/*to prevent draggables from being made too small to see*/
.fillRight, .fillRight,
.fillLeft, .fillLeft,
#WorldInfo, #WorldInfo,
#floatingPrompt { #floatingPrompt {
min-width: unset; min-width: 100px !important;
min-height: 100px !important;
position: fixed; position: fixed;
} }
@@ -4656,9 +4659,15 @@ body.waifuMode .zoomed_avatar {
align-items: start; align-items: start;
align-content: start; align-content: start;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden
} }
.mes_buttons {
font-size: calc(var(--mainFontSize)*1.2)
}
;
.drag-grabber, .drag-grabber,
.pull-tab { .pull-tab {
display: none !important; display: none !important;
@@ -5049,4 +5058,4 @@ body.waifuMode .zoomed_avatar {
background-color: var(--SmartThemeBlurTintColor); background-color: var(--SmartThemeBlurTintColor);
text-align: center; text-align: center;
line-height: 14px; line-height: 14px;
} }

View File

@@ -1 +1,23 @@
{"name":"Default (Minimal Light)","blur_strength":10,"main_text_color":"rgba(0, 0, 0, 1)","italics_text_color":"rgba(104, 104, 104, 1)","quote_text_color":"rgba(191, 154, 81, 1)","fastui_bg_color":"rgba(225, 225, 225, 1)","blur_tint_color":"rgba(228, 228, 228, 0.76)","shadow_color":"rgba(0, 0, 0, 0.5)","shadow_width":2,"font_scale":1,"fast_ui_mode":true,"waifuMode":false,"avatar_style":0,"chat_display":0,"noShadows":true,"sheld_width":0,"timer_enabled":false,"hotswap_enabled":false} {
"name": "Default (Minimal Light) v2",
"blur_strength": 10,
"main_text_color": "rgba(89, 89, 89, 1)",
"italics_text_color": "rgba(104, 104, 104, 1)",
"quote_text_color": "rgba(191, 154, 81, 1)",
"blur_tint_color": "rgba(228, 228, 228, 0.76)",
"user_mes_blur_tint_color": "",
"bot_mes_blur_tint_color": "",
"shadow_color": "rgba(0, 0, 0, 0.5)",
"shadow_width": 2,
"font_scale": 1,
"fast_ui_mode": true,
"waifuMode": false,
"avatar_style": 0,
"chat_display": 0,
"noShadows": true,
"sheld_width": 0,
"timer_enabled": false,
"timestamps_enabled": "",
"mesIDDisplay_enabled": "",
"hotswap_enabled": false
}

View File

@@ -2262,7 +2262,7 @@ app.post('/editworldinfo', jsonParser, (request, response) => {
return response.status(400).send('Is not a valid world info file'); return response.status(400).send('Is not a valid world info file');
} }
const filename = `${request.body.name}.json`; const filename = `${sanitize(request.body.name)}.json`;
const pathToFile = path.join(directories.worlds, filename); const pathToFile = path.join(directories.worlds, filename);
fs.writeFileSync(pathToFile, JSON.stringify(request.body.data, null, 4)); fs.writeFileSync(pathToFile, JSON.stringify(request.body.data, null, 4));

View File

@@ -5,6 +5,7 @@ declare enum ModelGenerationInputStableSamplers {
"k_lms" = "k_lms", "k_lms" = "k_lms",
"k_heun" = "k_heun", "k_heun" = "k_heun",
"k_euler" = "k_euler", "k_euler" = "k_euler",
"k_euler_a" = "k_euler_a",
"k_dpm_2" = "k_dpm_2", "k_dpm_2" = "k_dpm_2",
"k_dpm_2_a" = "k_dpm_2_a", "k_dpm_2_a" = "k_dpm_2_a",
"DDIM" = "DDIM", "DDIM" = "DDIM",

File diff suppressed because one or more lines are too long