This commit is contained in:
Cohee1207
2023-05-06 15:12:19 +03:00
12 changed files with 756 additions and 261 deletions

View File

@@ -417,6 +417,21 @@
</div> </div>
</div> </div>
</div> </div>
<div class="range-block">
<div class="range-block-title">
Top-p
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="top_p_openai" name="volume" min="0" max="1" step="0.01">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="top_p_openai" id="top_p_counter_openai">
select
</div>
</div>
</div>
</div>
</div> </div>
<div id="range_block_poe"> <div id="range_block_poe">
<div class="range-block"> <div class="range-block">
@@ -1185,6 +1200,15 @@
<option value="3">Sentencepiece (LLaMA)</option> <option value="3">Sentencepiece (LLaMA)</option>
</select> </select>
</div> </div>
<div class="range-block">
<div class="range-block-title justifyLeft">
Token Padding
<a href="/notes#tokenpadding" class="notes-link" target="_blank">
<span class="note-link-span">?</span>
</a>
</div>
<input id="token_padding" class="text_pole" type="number" min="-2048" max="2048" />
</div>
<label class="checkbox_label" for="always-force-name2-checkbox"> <label class="checkbox_label" for="always-force-name2-checkbox">
<input id="always-force-name2-checkbox" type="checkbox" /> <input id="always-force-name2-checkbox" type="checkbox" />
Always add character's name to prompt Always add character's name to prompt
@@ -1323,54 +1347,6 @@
<div name="UI Customization" class="flex-container drawer25pWidth"> <div name="UI Customization" class="flex-container drawer25pWidth">
<div class="ui-settings"> <div class="ui-settings">
<h4>UI Customization</h4> <h4>UI Customization</h4>
<div id="font-blur-UIpresets-block" class="flex-container flexFlowColumn">
<div id="font-scale-block" class="range-block">
<div class="range-block-title">
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">
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">
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> <div>
Avatar Style:<br> Avatar Style:<br>
<label> <label>
@@ -1418,6 +1394,16 @@
♡ Waifu Mode ♡ ♡ Waifu Mode ♡
</label> </label>
<label for="messageTimerEnabled" class="checkbox_label">
<input id="messageTimerEnabled" type="checkbox" />
Message Timer
</label>
<label for="hotswapEnabled" class="checkbox_label">
<input id="hotswapEnabled" type="checkbox" />
Characters Hotswap
</label>
<label for="movingUImode" class="checkbox_label"> <label for="movingUImode" class="checkbox_label">
<input id="movingUImode" type="checkbox" /> <input id="movingUImode" type="checkbox" />
Movable UI Panels Movable UI Panels
@@ -1455,6 +1441,53 @@
<toolcool-color-picker id="blur-tint-color-picker"></toolcool-color-picker> <toolcool-color-picker id="blur-tint-color-picker"></toolcool-color-picker>
Blur Tint Blur Tint
</div> </div>
<div id="font-blur-UIpresets-block" class="flex-container flexFlowColumn">
<div id="font-scale-block" class="range-block">
<div class="range-block-title">
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">
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">
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"> <div id="UI-presets-block" class="flex-container flexFlowColumn">
<h4> <h4>
UI Theme Preset UI Theme Preset
@@ -1501,6 +1534,10 @@
<input id="auto_fix_generated_markdown" type="checkbox" /> <input id="auto_fix_generated_markdown" type="checkbox" />
Auto-fix Markdown Auto-fix Markdown
</label> </label>
<label class="checkbox_label" for="allow_name2_display">
<input id="allow_name2_display" type="checkbox" />
Allow {{char}}: display in bot messages
</label>
<label for="auto_scroll_chat_to_bottom"> <label for="auto_scroll_chat_to_bottom">
<input id="auto_scroll_chat_to_bottom" type="checkbox" /> <input id="auto_scroll_chat_to_bottom" type="checkbox" />
Auto-scroll Chat Auto-scroll Chat
@@ -1619,6 +1656,8 @@
<div class="fa-solid checked fa-lock" alt=""></div> <div class="fa-solid checked fa-lock" alt=""></div>
</label> </label>
</div> </div>
<div class="hotswap flex-container justifyCenter">
</div>
<div id="right-nav-panel-tabs"> <div id="right-nav-panel-tabs">
<div class="right_menu_button fa-solid fa-list-ul" id="rm_button_characters" title="Select/Create Characters"></div> <div class="right_menu_button fa-solid fa-list-ul" id="rm_button_characters" title="Select/Create Characters"></div>
<div class="right_menu_button" id="rm_button_selected_ch"> <div class="right_menu_button" id="rm_button_selected_ch">
@@ -1627,8 +1666,7 @@
</div> </div>
</div> </div>
<div name="Solo Char Create/Edit Panel" id="rm_ch_create_block" class="right_menu flex-container flexFlowColumn" style="display: none;">
<div id="rm_ch_create_block" class="right_menu flex-container flexFlowColumn" style="display: none;">
<form id="form_create" action="javascript:void(null);" method="post" enctype="multipart/form-data"> <form id="form_create" action="javascript:void(null);" method="post" enctype="multipart/form-data">
<div id="avatar-and-name-block"> <div id="avatar-and-name-block">
@@ -1705,68 +1743,103 @@
<!-- now back to normal divs for display purposes--> <!-- now back to normal divs for display purposes-->
</form> </form>
</div> </div>
<div id="rm_group_chats_block" class="right_menu">
<div id="rm_group_top_bar"> <div name="Group Chat Edit Panel" id="rm_group_chats_block" class="right_menu flex-container flexNoGap">
<div id="rm_button_back_from_group" class="menu_button fa-solid fa-left-long"></div>
<div class="inline-drawer wide100p flexFlowColumn">
<div id="groupControlsToggle" class="inline-drawer-toggle inline-drawer-header">
Group Controls
<div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
</div>
<div class="inline-drawer-content">
<div name="group-metadata-controls" class="marginTopBot5">
<input id="rm_group_chat_name" class="text_pole" type="text" name="chat_name" placeholder="Chat Name (Optional)" maxlength="100" /> <input id="rm_group_chat_name" class="text_pole" type="text" name="chat_name" placeholder="Chat Name (Optional)" maxlength="100" />
<div id="group_favorite_button" class="menu_button fa-solid fa-star" title="Add to Favorites"></div>
<input id="rm_group_fav" type="hidden" />
<div id="rm_group_submit" class="menu_button fa-solid fa-check" title="Create"></div>
<div id="rm_group_delete" class="menu_button fa-solid fa-trash-can" title="Delete"></div>
</div>
<div id="rm_group_buttons">
<div class="flex1">
<h5>
Group reply strategy
<a href="/notes#replyorderstrategies" class="notes-link" target="_blank">
<span class="note-link-span">?</span>
</a>
</h5>
<label class="checkbox_label">
<input type="radio" name="rm_group_activation_strategy" value="0" />
Natural order
</label>
<label class="checkbox_label">
<input type="radio" name="rm_group_activation_strategy" value="1" />
List order
</label>
</div>
<div class="flex1">
<label class="checkbox_label">
<input id="rm_group_allow_self_responses" type="checkbox" />
Allow self responses
</label>
<label id="rm_group_automode_label" class="checkbox_label">
<input id="rm_group_automode" type="checkbox" />
Auto Mode
</label>
</div>
</div>
<div id="group_tags_div" class="wide100p"> <div id="group_tags_div" class="wide100p">
<div class="tag_controls"> <div class="tag_controls">
<input id="groupTagInput" class="text_pole tag_input flex1" placeholder="Search / Create tags" maxlength="25" /> <input id="groupTagInput" class="text_pole tag_input flex1" placeholder="Search / Create tags" maxlength="25" />
<div class="tags_view menu_button fa-solid fa-tags" title="View all tags"></div> <div class="tags_view menu_button fa-solid fa-tags" title="View all tags"></div>
</div> </div>
<div id="groupTagList" class="tags"></div> <div id="groupTagList" class="tags paddingTopBot5"></div>
</div> </div>
<div id="rm_group_top_bar" class="flex-container spaceEvenly width100p">
<div name="GroupStragegyAndOrder" id="rm_group_buttons" class="fontsize80p flex-container paddingLeftRight5">
<div class="">
<div class="flex-container flexnowrap width100p whitespacenowrap">
Group reply strategy
<a href="/notes#replyorderstrategies" class="notes-link" target="_blank">
<span class="note-link-span">?</span>
</a>
</div>
<label class="checkbox_label flexnowrap whitespacenowrap">
<input type="radio" name="rm_group_activation_strategy" value="0" />
Natural order
</label>
<label class="checkbox_label flexnowrap whitespacenowrap">
<input type="radio" name="rm_group_activation_strategy" value="1" />
List order
</label>
</div>
<div class="">
<label class="checkbox_label whitespacenowrap">
<input id="rm_group_allow_self_responses" type="checkbox" />
Allow self responses
</label>
<label id="rm_group_automode_label" class="checkbox_label whitespacenowrap">
<input id="rm_group_automode" type="checkbox" />
Auto Mode
</label>
</div>
</div>
<div name="GroupFavDelOkBack" class="flex-container flexGap5 spaceEvenly">
<div id="rm_button_back_from_group" class="heightFitContent margin0 menu_button fa-solid fa-left-long"></div>
<div id="rm_group_scenario" class="heightFitContent margin0 menu_button fa-solid fa-scroll" title="Set a group chat scenario"></div>
<div id="group_favorite_button" class="heightFitContent margin0 menu_button fa-solid fa-star" title="Add to Favorites"></div>
<input id="rm_group_fav" type="hidden" />
<div id="rm_group_submit" class="heightFitContent margin0 menu_button fa-solid fa-check" title="Create"></div>
<div id="rm_group_delete" class="heightFitContent margin0 menu_button fa-solid fa-trash-can" title="Delete"></div>
</div>
</div>
</div>
</div>
</div>
<div class="inline-drawer wide100p flexFlowColumn">
<div id="groupAddMemberListToggle" class="inline-drawer-toggle inline-drawer-header">
Add Members
<div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
</div>
<div class="inline-drawer-content">
<div name="Unadded Char List" class="flex-container flexFlowColumn overflowYAuto flex1">
<div id="rm_group_add_members_header"> <div id="rm_group_add_members_header">
<h3>Add Members</h3>
<input id="rm_group_filter" class="text_pole" type="search" placeholder="Filter..." maxlength="100" /> <input id="rm_group_filter" class="text_pole" type="search" placeholder="Filter..." maxlength="100" />
<div id="group_fav_filter" class="menu_button fa-solid fa-ranking-star" title="Show only favorites"></div> <div id="group_fav_filter" class="menu_button fa-solid fa-ranking-star" title="Show only favorites"></div>
</div> </div>
<div class="flex-container flexFlowColumn flexNoGap overflowYAuto wide100p flexGrow"> <div id="rm_group_add_members" class="overflowYAuto flex-container"></div>
<div id="rm_group_add_members"></div>
<h3>Current Members</h3>
<div id="rm_group_members"></div>
</div> </div>
</div> </div>
</div>
<div class="inline-drawer wide100p flexFlowColumn">
<div id="groupCurrentMemberListToggle" class="inline-drawer-toggle inline-drawer-header">
Current Members
<div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div>
</div>
<div class="inline-drawer-content">
<div name="Current Group Members" class="flex-container flexFlowColumn overflowYAuto flex1">
<div id="rm_group_members" class="overflowYAuto flex-container"></div>
</div>
</div>
</div>
</div>
<div id="rm_character_import" class="right_menu" style="display: none;"> <div id="rm_character_import" class="right_menu" style="display: none;">
<form id="form_import" action="javascript:void(null);" method="post" enctype="multipart/form-data"> <form id="form_import" action="javascript:void(null);" method="post" enctype="multipart/form-data">
<input multiple type="file" id="character_import_file" accept=".json, image/png, image/webp" name="avatar"> <input multiple type="file" id="character_import_file" accept=".json, image/png, image/webp" name="avatar">
<input id="character_import_file_type" name="file_type" class="text_pole" maxlength="999" size="2" value="" autocomplete="off"> <input id="character_import_file_type" name="file_type" class="text_pole" maxlength="999" size="2" value="" autocomplete="off">
</form> </form>
</div> </div>
<div id="rm_characters_block" class="right_menu">
<div name="Character List Panel" id="rm_characters_block" class="right_menu">
<div id="charListFixedTop"> <div id="charListFixedTop">
<div class="form_create_bottom_buttons_block"> <div class="form_create_bottom_buttons_block">
<div id="rm_button_create" title="Create New Character" class="menu_button fa-solid fa-user-plus "></div> <div id="rm_button_create" title="Create New Character" class="menu_button fa-solid fa-user-plus "></div>
@@ -1945,6 +2018,21 @@
<!-- templates for JS to reuse when needed --> <!-- templates for JS to reuse when needed -->
<div id="group_scenario_template" class="template_element">
<div class="group_scenario range-block flexFlowColumn flex-container">
<div class="range-block-title title_restorable">
<h3>Group Chat Scenario Override</h3>
<div title="Remove" class="menu_button fa-solid fa-trash-can remove_scenario_override"></div>
</div>
<div class="range-block-counter justifyLeft flex-container flexFlowColumn">
All group members will use the following scenario text instead of what is specified in their character cards.
</div>
<div class="range-block-range wide100p">
<textarea class="wide100p group_chat_scenario" class="text_pole" rows="5" placeholder="Type here..."></textarea>
</div>
</div>
</div>
<div id="past_chat_template" class="template_element"> <div id="past_chat_template" class="template_element">
<div class="select_chat_block_wrapper"> <div class="select_chat_block_wrapper">
<div class="select_chat_block" file_name=""> <div class="select_chat_block" file_name="">
@@ -2203,6 +2291,12 @@
</div> </div>
</div> </div>
<div id="hotswap_template" class="template_element">
<div class="hotswapAvatar">
<img src="/img/ai4.png">
</div>
</div>
<!-- chat and input bar --> <!-- chat and input bar -->
<div id="typing_indicator_template" class="template_element"> <div id="typing_indicator_template" class="template_element">
<div class="typing_indicator"><span class="typing_indicator_name">CHAR</span> is typing</div> <div class="typing_indicator"><span class="typing_indicator_name">CHAR</span> is typing</div>

View File

@@ -422,6 +422,8 @@ To import Character.AI chats, use this tool: [https://github.com/0x000011b/chara
## Tokenizer ## Tokenizer
**Important: This section doesn't apply to OpenAI API. SillyTavern will always use a matching tokenizer for OpenAI models.**
A tokenizer is a tool that breaks down a piece of text into smaller units called tokens. These tokens can be individual words or even parts of words, such as prefixes, suffixes, or punctuation. A rule of thumb is that one token generally corresponds to 3~4 characters of text. A tokenizer is a tool that breaks down a piece of text into smaller units called tokens. These tokens can be individual words or even parts of words, such as prefixes, suffixes, or punctuation. A rule of thumb is that one token generally corresponds to 3~4 characters of text.
SillyTavern can use the following tokenizers while forming a request to the AI backend: SillyTavern can use the following tokenizers while forming a request to the AI backend:
@@ -431,6 +433,18 @@ SillyTavern can use the following tokenizers while forming a request to the AI b
3. (Legacy) GPT-2/3 tokenizer. Used by original TavernAI. **Pick this if you're unsure.** More info: [gpt-2-3-tokenizer](https://github.com/josephrocca/gpt-2-3-tokenizer). 3. (Legacy) GPT-2/3 tokenizer. Used by original TavernAI. **Pick this if you're unsure.** More info: [gpt-2-3-tokenizer](https://github.com/josephrocca/gpt-2-3-tokenizer).
4. Sentencepiece tokenizer. Used by LLaMA model family: Alpaca, Vicuna, Koala, etc. **Pick if you use a LLaMA model.** 4. Sentencepiece tokenizer. Used by LLaMA model family: Alpaca, Vicuna, Koala, etc. **Pick if you use a LLaMA model.**
## Token Padding
**Important: This section doesn't apply to OpenAI API. SillyTavern will always use a matching tokenizer for OpenAI models.**
SillyTavern cannot use a proper tokenizer provided by the model running on a remote instance of KoboldAI or Oobabooga's TextGen, so all token counts assumed during prompt generation are estimated based on the selected [tokenizer](#Tokenizer) type.
Since the results of tokenization can be inaccurate on context sizes close to the model-defined maximum, some parts of the prompt may be trimmed or dropped, which may negatively affect the coherence of character definitions.
To prevent this, SillyTavern allocates a portion of the context size as padding to avoid adding more chat items than the model can accommodate. If you find that some part of the prompt is trimmed even with the most-matching tokenizer selected, adjust the padding so the description is not truncated.
You can input negative values for reverse padding, which allows allocating more than the set maximum amount of tokens.
## Advanced Formatting ## Advanced Formatting
The settings provided in this section allow for more control over the prompt building strategy. Most specifics of the prompt building depend on whether a Pygmalion model is selected or special formatting is force-enabled. The core differences between the formatting schemas are listed below. The settings provided in this section allow for more control over the prompt building strategy. Most specifics of the prompt building depend on whether a Pygmalion model is selected or special formatting is force-enabled. The core differences between the formatting schemas are listed below.

View File

@@ -1,4 +1,4 @@
import { humanizedDateTime } from "./scripts/RossAscends-mods.js"; import { humanizedDateTime, favsToHotswap } from "./scripts/RossAscends-mods.js";
import { encode } from "../scripts/gpt-2-3-tokenizer/mod.js"; import { encode } from "../scripts/gpt-2-3-tokenizer/mod.js";
import { GPT3BrowserTokenizer } from "../scripts/gpt-3-tokenizer/gpt3-tokenizer.js"; import { GPT3BrowserTokenizer } from "../scripts/gpt-3-tokenizer/gpt3-tokenizer.js";
import { import {
@@ -143,7 +143,7 @@ export {
setRightTabSelectedClass, setRightTabSelectedClass,
openCharacterChat, openCharacterChat,
saveChat, saveChat,
messageFormating, messageFormatting,
getExtensionPrompt, getExtensionPrompt,
showSwipeButtons, showSwipeButtons,
hideSwipeButtons, hideSwipeButtons,
@@ -240,7 +240,7 @@ window.filterByFav = false;
const durationSaveEdit = 200; const durationSaveEdit = 200;
const saveSettingsDebounced = debounce(() => saveSettings(), durationSaveEdit); const saveSettingsDebounced = debounce(() => saveSettings(), durationSaveEdit);
const saveCharacterDebounced = debounce(() => $("#create_button").click(), durationSaveEdit); const saveCharacterDebounced = debounce(() => $("#create_button").trigger('click'), durationSaveEdit);
const getStatusDebounced = debounce(() => getStatus(), 90000); const getStatusDebounced = debounce(() => getStatus(), 90000);
const saveChatDebounced = debounce(() => saveChatConditional(), 1000); const saveChatDebounced = debounce(() => saveChatConditional(), 1000);
@@ -472,7 +472,6 @@ var preset_settings = "gui";
var user_avatar = "you.png"; var user_avatar = "you.png";
var amount_gen = 80; //default max length of AI generated responses var amount_gen = 80; //default max length of AI generated responses
var max_context = 2048; var max_context = 2048;
let padding_tokens = 64; // reserved tokens to prevent prompt overflow
var is_pygmalion = false; var is_pygmalion = false;
var tokens_already_generated = 0; var tokens_already_generated = 0;
@@ -734,9 +733,10 @@ function printCharacters() {
// Add to the list // Add to the list
$("#rm_print_characters_block").append(template); $("#rm_print_characters_block").append(template);
}); });
$("#rm_print_characters_block").prepend(`<hr>`);
printTags(); printTags();
printGroups(); printGroups();
favsToHotswap();
sortCharactersList(); sortCharactersList();
} }
@@ -931,7 +931,7 @@ export async function reloadCurrentChat() {
} }
} }
function messageFormating(mes, ch_name, isSystem, forceAvatar) { function messageFormatting(mes, ch_name, isSystem, isUser) {
if (!mes) { if (!mes) {
mes = ''; mes = '';
} }
@@ -967,9 +967,9 @@ function messageFormating(mes, ch_name, isSystem, forceAvatar) {
}); });
} }
/* if (ch_name && (forceAvatar || ch_name !== name1)) { if (!power_user.allow_name2_display && ch_name && !isUser && !isSystem) {
mes = mes.replaceAll(ch_name + ":", ""); mes = mes.replaceAll(`${ch_name}:`, "");
} */ }
return mes; return mes;
} }
@@ -1057,13 +1057,13 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true
if (count_view_mes == 0) { if (count_view_mes == 0) {
messageText = substituteParams(messageText); messageText = substituteParams(messageText);
} }
messageText = messageFormating( messageText = messageFormatting(
messageText, messageText,
characterName, characterName,
isSystem, isSystem,
mes.force_avatar mes.is_user,
); );
const bias = messageFormating(mes.extra?.bias ?? ""); const bias = messageFormatting(mes.extra?.bias ?? "");
let params = { let params = {
mesId: count_view_mes, mesId: count_view_mes,
@@ -1356,6 +1356,8 @@ function applyFavFilter(enabled) {
} }
} }
class StreamingProcessor { class StreamingProcessor {
showStopButton(messageId) { showStopButton(messageId) {
if (messageId == -1) { if (messageId == -1) {
@@ -1392,8 +1394,24 @@ class StreamingProcessor {
return messageId; return messageId;
} }
removePrefix(text) {
const name1Marker = `${name1}: `;
const name2Marker = `${name2}: `;
if (text) {
if (text.startsWith(name1Marker)) {
text = text.replace(name1Marker, '');
}
if (text.startsWith(name2Marker)) {
text = text.replace(name2Marker, '');
}
}
return text;
}
onProgressStreaming(messageId, text) { onProgressStreaming(messageId, text) {
const isImpersonate = this.type == "impersonate"; const isImpersonate = this.type == "impersonate";
text = this.removePrefix(text);
let processedText = cleanUpMessage(text, isImpersonate); let processedText = cleanUpMessage(text, isImpersonate);
let result = extractNameFromMessage(processedText, this.force_name2, isImpersonate); let result = extractNameFromMessage(processedText, this.force_name2, isImpersonate);
let isName = result.this_mes_is_name; let isName = result.this_mes_is_name;
@@ -1414,7 +1432,12 @@ class StreamingProcessor {
chat[messageId]['swipes'][chat[messageId]['swipe_id']] = processedText; chat[messageId]['swipes'][chat[messageId]['swipe_id']] = processedText;
} }
let formattedText = messageFormating(processedText, chat[messageId].name, chat[messageId].is_system, chat[messageId].force_avatar); let formattedText = messageFormatting(
processedText,
chat[messageId].name,
chat[messageId].is_system,
chat[messageId].is_user,
);
const mesText = $(`#chat .mes[mesid="${messageId}"] .mes_text`); const mesText = $(`#chat .mes[mesid="${messageId}"] .mes_text`);
mesText.html(formattedText); mesText.html(formattedText);
$(`#chat .mes[mesid="${messageId}"] .mes_timer`).text(timePassed.timerValue).attr('title', timePassed.timerTitle); $(`#chat .mes[mesid="${messageId}"] .mes_timer`).text(timePassed.timerValue).attr('title', timePassed.timerTitle);
@@ -1627,10 +1650,11 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
addOneMessage(chat[chat.length - 1]); addOneMessage(chat[chat.length - 1]);
} }
//////////////////////////////////// ////////////////////////////////////
let charDescription = baseChatReplace($.trim(characters[this_chid].description), name1, name2); const scenarioText = chat_metadata['scenario'] || characters[this_chid].scenario;
let charPersonality = baseChatReplace($.trim(characters[this_chid].personality), name1, name2); let charDescription = baseChatReplace(characters[this_chid].description.trim(), name1, name2);
let Scenario = baseChatReplace($.trim(characters[this_chid].scenario), name1, name2); let charPersonality = baseChatReplace(characters[this_chid].personality.trim(), name1, name2);
let mesExamples = baseChatReplace($.trim(characters[this_chid].mes_example), name1, name2); let Scenario = baseChatReplace(scenarioText.trim(), name1, name2);
let mesExamples = baseChatReplace(characters[this_chid].mes_example.trim(), name1, name2);
// Parse example messages // Parse example messages
if (!mesExamples.startsWith('<START>')) { if (!mesExamples.startsWith('<START>')) {
@@ -1777,7 +1801,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
allAnchors, allAnchors,
quiet_prompt, quiet_prompt,
].join('').replace(/\r/gm, ''); ].join('').replace(/\r/gm, '');
return getTokenCount(encodeString, padding_tokens) < this_max_context; return getTokenCount(encodeString, power_user.token_padding) < this_max_context;
} }
// Force pinned examples into the context // Force pinned examples into the context
@@ -1834,7 +1858,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
arrMes = arrMes.reverse(); arrMes = arrMes.reverse();
arrMes.forEach(function (item, i, arr) {//For added anchors and others arrMes.forEach(function (item, i, arr) {//For added anchors and others
if (i === arrMes.length - 1 && $.trim(item).substr(0, (name1 + ":").length) != name1 + ":") { if (i === arrMes.length - 1 && !item.trim().startsWith(name1 + ":")) {
if (textareaText == "") { if (textareaText == "") {
item = item.substr(0, item.length - 1); item = item.substr(0, item.length - 1);
} }
@@ -1844,24 +1868,26 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
//anchorAndPersonality = "[Genre: roleplay chat][Tone: very long messages with descriptions]"; //anchorAndPersonality = "[Genre: roleplay chat][Tone: very long messages with descriptions]";
let personalityAndAnchor = [charPersonality, anchorTop].filter(x => x).join(' '); let personalityAndAnchor = [charPersonality, anchorTop].filter(x => x).join(' ');
if (personalityAndAnchor) { if (personalityAndAnchor) {
item += "[" + personalityAndAnchor + ']\n'; item += "[" + personalityAndAnchor + "]\n";
} }
} }
if (i === arrMes.length - 1 && coreChat.length > bottomAnchorThreshold && $.trim(item).substr(0, (name1 + ":").length) == name1 + ":" && !is_pygmalion) {//For add anchor in end if (i === arrMes.length - 1 && coreChat.length > bottomAnchorThreshold && item.trim().startsWith(name1 + ":") && !is_pygmalion) {//For add anchor in end
item = item.substr(0, item.length - 1);
//chatString+=postAnchor+"\n";//"[Writing style: very long messages]\n"; //chatString+=postAnchor+"\n";//"[Writing style: very long messages]\n";
item = item + anchorBottom + "\n"; if (anchorBottom) {
item = item.replace(/\n$/, " ");
item += anchorBottom + "\n";
}
} }
if (is_pygmalion) { if (is_pygmalion) {
if (i === arrMes.length - 1 && $.trim(item).substr(0, (name1 + ":").length) == name1 + ":") {//for add name2 when user sent if (i === arrMes.length - 1 && item.trim().startsWith(name1 + ":")) {//for add name2 when user sent
item = item + name2 + ":"; item = item + name2 + ":";
} }
if (i === arrMes.length - 1 && $.trim(item).substr(0, (name1 + ":").length) != name1 + ":") {//for add name2 when continue if (i === arrMes.length - 1 && !item.trim().startsWith(name1 + ":")) {//for add name2 when continue
if (textareaText == "") { if (textareaText == "") {
item = item + '\n' + name2 + ":"; item = item + '\n' + name2 + ":";
} }
} }
if ($.trim(item).indexOf(name1) === 0) { if (item.trim().startsWith(name1)) {
item = item.replace(name1 + ':', 'You:'); item = item.replace(name1 + ':', 'You:');
} }
} }
@@ -1930,7 +1956,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
allAnchors, allAnchors,
quiet_prompt, quiet_prompt,
].join('').replace(/\r/gm, ''); ].join('').replace(/\r/gm, '');
let thisPromtContextSize = getTokenCount(prompt, padding_tokens); let thisPromtContextSize = getTokenCount(prompt, power_user.token_padding);
if (thisPromtContextSize > this_max_context) { //if the prepared prompt is larger than the max context size... if (thisPromtContextSize > this_max_context) { //if the prepared prompt is larger than the max context size...
if (count_exm_add > 0) { // ..and we have example mesages.. if (count_exm_add > 0) { // ..and we have example mesages..
@@ -2007,7 +2033,6 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
if (power_user.collapse_newlines) { if (power_user.collapse_newlines) {
finalPromt = collapseNewlines(finalPromt); finalPromt = collapseNewlines(finalPromt);
} }
//console.log(`---Calculated Prompt Tokens: ${getTokenCount(finalPromt, padding_tokens)}`);
let this_amount_gen = parseInt(amount_gen); // how many tokens the AI will be requested to generate let this_amount_gen = parseInt(amount_gen); // how many tokens the AI will be requested to generate
let this_settings = koboldai_settings[koboldai_setting_names[preset_settings]]; let this_settings = koboldai_settings[koboldai_setting_names[preset_settings]];
@@ -2338,7 +2363,7 @@ function shouldContinueMultigen(getMessage) {
function extractNameFromMessage(getMessage, force_name2, isImpersonate) { function extractNameFromMessage(getMessage, force_name2, isImpersonate) {
const nameToTrim = isImpersonate ? name1 : name2; const nameToTrim = isImpersonate ? name1 : name2;
let this_mes_is_name = true; let this_mes_is_name = true;
if (getMessage.indexOf(nameToTrim + ":") === 0) { if (getMessage.startsWith(nameToTrim + ":")) {
getMessage = getMessage.replace(nameToTrim + ':', ''); getMessage = getMessage.replace(nameToTrim + ':', '');
getMessage = getMessage.trimStart(); getMessage = getMessage.trimStart();
} else { } else {
@@ -2671,6 +2696,8 @@ async function renameCharacter() {
async function saveChat(chat_name, withMetadata) { async function saveChat(chat_name, withMetadata) {
const metadata = { ...chat_metadata, ...(withMetadata || {}) }; const metadata = { ...chat_metadata, ...(withMetadata || {}) };
let file_name = chat_name ?? characters[this_chid].chat; let file_name = chat_name ?? characters[this_chid].chat;
characters[this_chid]['date_last_chat'] = Date.now();
sortCharactersList();
chat.forEach(function (item, i) { chat.forEach(function (item, i) {
if (item["is_group"]) { if (item["is_group"]) {
alert('Trying to save group chat with regular saveChat function. Aborting to prevent corruption.'); alert('Trying to save group chat with regular saveChat function. Aborting to prevent corruption.');
@@ -2719,33 +2746,49 @@ async function saveChat(chat_name, withMetadata) {
}); });
} }
function read_avatar_load(input) { async function read_avatar_load(input) {
if (input.files && input.files[0]) { if (input.files && input.files[0]) {
const reader = new FileReader(); const reader = new FileReader();
if (selected_button == "create") { if (selected_button == "create") {
create_save_avatar = input.files; create_save_avatar = input.files;
} }
reader.onload = function (e) { reader.onload = async function (e) {
if (selected_button == "character_edit") {
saveCharacterDebounced();
}
$("#avatar_load_preview").attr("src", e.target.result); $("#avatar_load_preview").attr("src", e.target.result);
//.width(103)
//.height(83);
//console.log(e.target.result.name);
};
reader.readAsDataURL(input.files[0]); if (menu_type != "create") {
$("#create_button").trigger('click');
if (this_chid) { const formData = new FormData($("#form_create").get(0));
fetch(getThumbnailUrl('avatar', characters[this_chid].avatar), {
$(".mes").each(async function () {
if ($(this).attr("is_system") == 'true') {
return;
}
if ($(this).attr("is_user") == 'true') {
return;
}
if ($(this).attr("ch_name") == formData.get('ch_name')) {
const previewSrc = $("#avatar_load_preview").attr("src");
const avatar = $(this).find(".avatar img");
avatar.attr('src', default_avatar);
await delay(1);
avatar.attr('src', previewSrc);
}
});
await delay(durationSaveEdit);
await fetch(getThumbnailUrl('avatar', formData.get('avatar_url')), {
method: 'GET', method: 'GET',
headers: { headers: {
'pragma': 'no-cache', 'pragma': 'no-cache',
'cache-control': 'no-cache', 'cache-control': 'no-cache',
} }
}).then(() => console.log('Avatar refreshed')); });
console.log('Avatar refreshed');
} }
};
reader.readAsDataURL(input.files[0]);
} }
} }
@@ -3238,6 +3281,9 @@ function messageEditAuto(div) {
var text = mesBlock.find(".edit_textarea").val().trim(); var text = mesBlock.find(".edit_textarea").val().trim();
const bias = extractMessageBias(text); const bias = extractMessageBias(text);
chat[this_edit_mes_id]["mes"] = text; chat[this_edit_mes_id]["mes"] = text;
if (chat[this_edit_mes_id]["swipe_id"] !== undefined) {
chat[this_edit_mes_id]["swipes"][chat[this_edit_mes_id]["swipe_id"]] = text;
}
// editing old messages // editing old messages
if (!chat[this_edit_mes_id]["extra"]) { if (!chat[this_edit_mes_id]["extra"]) {
@@ -3245,7 +3291,12 @@ function messageEditAuto(div) {
} }
chat[this_edit_mes_id]["extra"]["bias"] = bias ?? null; chat[this_edit_mes_id]["extra"]["bias"] = bias ?? null;
mesBlock.find(".mes_text").val(''); mesBlock.find(".mes_text").val('');
mesBlock.find(".mes_text").val(messageFormating(text, this_edit_mes_chname, chat[this_edit_mes_id].is_system, chat[this_edit_mes_id].force_avatar)); mesBlock.find(".mes_text").val(messageFormatting(
text,
this_edit_mes_chname,
chat[this_edit_mes_id].is_system,
chat[this_edit_mes_id].is_user,
));
saveChatDebounced(); saveChatDebounced();
} }
@@ -3254,6 +3305,9 @@ function messageEditDone(div) {
var text = mesBlock.find(".edit_textarea").val().trim(); var text = mesBlock.find(".edit_textarea").val().trim();
const bias = extractMessageBias(text); const bias = extractMessageBias(text);
chat[this_edit_mes_id]["mes"] = text; chat[this_edit_mes_id]["mes"] = text;
if (chat[this_edit_mes_id]["swipe_id"] !== undefined) {
chat[this_edit_mes_id]["swipes"][chat[this_edit_mes_id]["swipe_id"]] = text;
}
// editing old messages // editing old messages
if (!chat[this_edit_mes_id]["extra"]) { if (!chat[this_edit_mes_id]["extra"]) {
@@ -3266,10 +3320,15 @@ function messageEditDone(div) {
mesBlock.find(".mes_edit_buttons").css("display", "none"); mesBlock.find(".mes_edit_buttons").css("display", "none");
mesBlock.find(".mes_edit").css("display", "inline-block"); mesBlock.find(".mes_edit").css("display", "inline-block");
mesBlock.find(".mes_text").append( mesBlock.find(".mes_text").append(
messageFormating(text, this_edit_mes_chname, chat[this_edit_mes_id].is_system, chat[this_edit_mes_id].force_avatar) messageFormatting(
text,
this_edit_mes_chname,
chat[this_edit_mes_id].is_system,
chat[this_edit_mes_id].is_user,
)
); );
mesBlock.find(".mes_bias").empty(); mesBlock.find(".mes_bias").empty();
mesBlock.find(".mes_bias").append(messageFormating(bias)); mesBlock.find(".mes_bias").append(messageFormatting(bias));
appendImageToMessage(chat[this_edit_mes_id], div.closest(".mes")); appendImageToMessage(chat[this_edit_mes_id], div.closest(".mes"));
addCopyToCodeBlocks(div.closest(".mes")); addCopyToCodeBlocks(div.closest(".mes"));
this_edit_mes_id = undefined; this_edit_mes_id = undefined;
@@ -3396,7 +3455,13 @@ function selectRightMenuWithAnimation(selectedMenuId) {
easing: animation_easing, easing: animation_easing,
complete: function () { }, complete: function () { },
}); });
// $(menu).find('#groupCurrentMemberListToggle').click();
} }
}) })
} }
@@ -3554,6 +3619,7 @@ function updateFavButtonState(state) {
$("#fav_checkbox").val(fav_ch_checked); $("#fav_checkbox").val(fav_ch_checked);
$("#favorite_button").toggleClass('fav_on', fav_ch_checked); $("#favorite_button").toggleClass('fav_on', fav_ch_checked);
$("#favorite_button").toggleClass('fav_off', !fav_ch_checked); $("#favorite_button").toggleClass('fav_off', !fav_ch_checked);
} }
function callPopup(text, type, inputValue = '') { function callPopup(text, type, inputValue = '') {
@@ -3818,8 +3884,11 @@ window["SillyTavern"].getContext = function () {
}; };
}; };
$(document).ready(function () { $(document).ready(function () {
//////////INPUT BAR FOCUS-KEEPING LOGIC///////////// //////////INPUT BAR FOCUS-KEEPING LOGIC/////////////
let S_TAFocused = false; let S_TAFocused = false;
@@ -4602,25 +4671,7 @@ $(document).ready(function () {
cache: false, cache: false,
contentType: false, contentType: false,
processData: false, processData: false,
success: function (html) { success: async function (html) {
/* Cohee: Not needed, since the rename routine forcefully reloads the chat
//currently this updates the displayed H2 name regardless of soft errors, doesn't detect actual errors.
let h2text = $("#character_name_pole").val();
console.log('about to change name! in h2');
$("#rm_button_selected_ch").children("h2").text(h2text);
*/
$(".mes").each(function () {
if ($(this).attr("is_system") == 'true') {
return;
}
if ($(this).attr("ch_name") != name1) {
$(this)
.children(".avatar")
.children("img")
.attr("src", $("#avatar_load_preview").attr("src"));
}
});
if (chat.length === 1) { if (chat.length === 1) {
var this_ch_mes = default_ch_mes; var this_ch_mes = default_ch_mes;
if ($("#firstmessage_textarea").val() != "") { if ($("#firstmessage_textarea").val() != "") {
@@ -4649,7 +4700,7 @@ $(document).ready(function () {
} }
} }
$("#create_button").removeAttr("disabled"); $("#create_button").removeAttr("disabled");
getCharacters(); await getCharacters();
$("#add_avatar_button").replaceWith( $("#add_avatar_button").replaceWith(
$("#add_avatar_button").val("").clone(true) $("#add_avatar_button").val("").clone(true)
@@ -4704,6 +4755,7 @@ $(document).ready(function () {
updateFavButtonState(!fav_ch_checked); updateFavButtonState(!fav_ch_checked);
if (menu_type != "create") { if (menu_type != "create") {
saveCharacterDebounced(); saveCharacterDebounced();
} }
}); });
@@ -5204,7 +5256,12 @@ $(document).ready(function () {
$(this) $(this)
.closest(".mes_block") .closest(".mes_block")
.find(".mes_text") .find(".mes_text")
.append(messageFormating(text, this_edit_mes_chname, chat[this_edit_mes_id].is_system, chat[this_edit_mes_id].force_avatar)); .append(messageFormatting(
text,
this_edit_mes_chname,
chat[this_edit_mes_id].is_system,
chat[this_edit_mes_id].is_user,
));
appendImageToMessage(chat[this_edit_mes_id], $(this).closest(".mes")); appendImageToMessage(chat[this_edit_mes_id], $(this).closest(".mes"));
addCopyToCodeBlocks($(this).closest(".mes")); addCopyToCodeBlocks($(this).closest(".mes"));
this_edit_mes_id = undefined; this_edit_mes_id = undefined;
@@ -5532,7 +5589,7 @@ $(document).ready(function () {
icon.toggleClass('openIcon closedIcon'); icon.toggleClass('openIcon closedIcon');
drawer.toggleClass('openDrawer closedDrawer'); drawer.toggleClass('openDrawer closedDrawer');
console.log(targetDrawerID); //console.log(targetDrawerID);
if (targetDrawerID === 'right-nav-panel') { if (targetDrawerID === 'right-nav-panel') {
$(this).closest('.drawer').find('.drawer-content').slideToggle({ $(this).closest('.drawer').find('.drawer-content').slideToggle({
duration: 200, duration: 200,

View File

@@ -12,16 +12,24 @@ import {
is_send_press, is_send_press,
getTokenCount, getTokenCount,
menu_type, menu_type,
selectRightMenuWithAnimation,
select_selected_character,
setCharacterId,
} from "../script.js"; } from "../script.js";
import {
select_group_chats,
} from "./group-chats.js";
import { import {
power_user, power_user,
send_on_enter_options, send_on_enter_options,
} from "./power-user.js"; } from "./power-user.js";
import { LoadLocal, SaveLocal, ClearLocal, CheckLocal, LoadLocalBool } from "./f-localStorage.js"; import { LoadLocal, SaveLocal, ClearLocal, CheckLocal, LoadLocalBool } from "./f-localStorage.js";
import { selected_group, is_group_generating } from "./group-chats.js"; import { selected_group, is_group_generating, getGroupAvatar, groups } from "./group-chats.js";
import { oai_settings } from "./openai.js"; import { oai_settings } from "./openai.js";
import { poe_settings } from "./poe.js"; import { poe_settings } from "./poe.js";
@@ -255,42 +263,74 @@ export function RA_CountCharTokens() {
//Auto Load Last Charcter -- (fires when active_character is defined and auto_load_chat is true) //Auto Load Last Charcter -- (fires when active_character is defined and auto_load_chat is true)
async function RA_autoloadchat() { async function RA_autoloadchat() {
if (document.getElementById('CharID0') !== null) { if (document.getElementById('CharID0') !== null) {
//console.log('char list loaded! clicking activeChar'); var charToAutoLoad = document.getElementById('CharID' + LoadLocal('ActiveChar'));
var CharToAutoLoad = document.getElementById('CharID' + LoadLocal('ActiveChar')); let groupToAutoLoad = document.querySelector(`.group_select[grid="${LoadLocal('ActiveGroup')}"]`);
//console.log(CharToAutoLoad); if (charToAutoLoad != null) { $(charToAutoLoad).click(); }
let autoLoadGroup = document.querySelector(`.group_select[grid="${LoadLocal('ActiveGroup')}"]`); else if (groupToAutoLoad != null) { $(groupToAutoLoad).click(); }
//console.log(autoLoadGroup);
if (CharToAutoLoad != null) {
// if the charcter list hadn't been loaded yet, try again.
} else { setTimeout(RA_autoloadchat, 100); }
}
// console.log('--ALC - clicking character'); export async function favsToHotswap() {
CharToAutoLoad.click(); const selector = ['#rm_print_characters_block .character_select', '#rm_print_characters_block .group_select'].join(',');
CharToAutoLoad.click(); const container = $('#rm_PinAndTabs .hotswap');
const template = $('#hotswap_template .hotswapAvatar');
container.empty();
const maxCount = 6;
let count = 0;
$(selector).each(function () {
if ($(this).hasClass('is_fav') && count < maxCount) {
const isCharacter = $(this).hasClass('character_select');
const isGroup = $(this).hasClass('group_select');
const grid = Number($(this).attr('grid'));
const chid = Number($(this).attr('chid'));
let thisHotSwapSlot = template.clone();
thisHotSwapSlot.toggleClass('character_select', isCharacter);
thisHotSwapSlot.toggleClass('group_select', isGroup);
thisHotSwapSlot.attr('grid', isGroup ? grid : '');
thisHotSwapSlot.attr('chid', isCharacter ? chid : '');
thisHotSwapSlot.data('id', isGroup ? grid : chid);
if (isGroup) {
const group = groups.find(x => x.id === grid);
const avatar = getGroupAvatar(group);
$(thisHotSwapSlot).find('img').replaceWith(avatar);
} }
else if (autoLoadGroup != null) {
//console.log('--ALC - clicking group'); if (isCharacter) {
autoLoadGroup.click(); const avatarUrl = $(this).find('img').attr('src');
autoLoadGroup.click(); $(thisHotSwapSlot).find('img').attr('src', avatarUrl);
} }
else {
console.log(CharToAutoLoad + ' ActiveChar local var - not found: ' + LoadLocal('ActiveChar')); $(thisHotSwapSlot).css('cursor', 'pointer');
container.append(thisHotSwapSlot);
count++;
}
});
//console.log('about to check for leftover selectors...')
// there are 6 slots in total,
if (count < maxCount) { //if any are left over
let leftOverSlots = maxCount - count;
for (let i = 1; i <= leftOverSlots; i++) {
container.append(template.clone());
} }
RestoreNavTab();
} else { } else {
//console.log('no char list yet..'); //console.log(`count was ${count} so no need to knock off any selectors!`);
setTimeout(RA_autoloadchat, 100); // if the charcter list hadn't been loaded yet, try again.
} }
} }
//only triggers when AutoLoadChat is enabled, consider adding this as an independent feature later.
function RestoreNavTab() { /* function RestoreNavTab() {
if ($('#rm_button_selected_ch').children("h2").text() !== '') { //check for a change in the character edit tab name if ($('#rm_button_selected_ch').children("h2").text() !== '') {
//console.log('detected ALC char finished loaded, proceeding to restore tab.');
$(SelectedNavTab).click(); //click to restore saved tab when name has changed (signalling char load is done) $(SelectedNavTab).click();
} else { } else {
setTimeout(RestoreNavTab, 100); //if not changed yet, check again after 100ms setTimeout(RestoreNavTab, 100);
}
} }
} */
//changes input bar and send button display depending on connection status //changes input bar and send button display depending on connection status
function RA_checkOnlineStatus() { function RA_checkOnlineStatus() {
if (online_status == "no_connection") { if (online_status == "no_connection") {
@@ -376,7 +416,7 @@ function isUrlOrAPIKey(string) {
function OpenNavPanels() { function OpenNavPanels() {
//auto-open R nav if locked and previously open //auto-open R nav if locked and previously open
if (LoadLocalBool("NavLockOn") == true && LoadLocalBool("NavOpened") == true) { if (LoadLocalBool("NavLockOn") == true && LoadLocalBool("NavOpened") == true) {
console.log("RA -- clicking right nav to open"); //console.log("RA -- clicking right nav to open");
$("#rightNavDrawerIcon").click(); $("#rightNavDrawerIcon").click();
} else { } else {
/* console.log('didnt see reason to open right nav on load: R-nav locked? ' + /* console.log('didnt see reason to open right nav on load: R-nav locked? ' +
@@ -555,7 +595,11 @@ $("document").ready(function () {
$(AutoConnectCheckbox).prop("checked", LoadLocalBool("AutoConnectEnabled")); $(AutoConnectCheckbox).prop("checked", LoadLocalBool("AutoConnectEnabled"));
$(AutoLoadChatCheckbox).prop("checked", LoadLocalBool("AutoLoadChatEnabled")); $(AutoLoadChatCheckbox).prop("checked", LoadLocalBool("AutoLoadChatEnabled"));
setTimeout(function () {
if (LoadLocalBool('AutoLoadChatEnabled') == true) { RA_autoloadchat(); } if (LoadLocalBool('AutoLoadChatEnabled') == true) { RA_autoloadchat(); }
}, 200);
//Autoconnect on page load if enabled, or when api type is changed //Autoconnect on page load if enabled, or when api type is changed
if (LoadLocalBool("AutoConnectEnabled") == true) { RA_autoconnect(); } if (LoadLocalBool("AutoConnectEnabled") == true) { RA_autoconnect(); }
$("#main_api").change(function () { $("#main_api").change(function () {
@@ -568,10 +612,10 @@ $("document").ready(function () {
$(RPanelPin).on("click", function () { $(RPanelPin).on("click", function () {
SaveLocal("NavLockOn", $(RPanelPin).prop("checked")); SaveLocal("NavLockOn", $(RPanelPin).prop("checked"));
if ($(RPanelPin).prop("checked") == true) { if ($(RPanelPin).prop("checked") == true) {
console.log('adding pin class to right nav'); //console.log('adding pin class to right nav');
$(RightNavPanel).addClass('pinnedOpen'); $(RightNavPanel).addClass('pinnedOpen');
} else { } else {
console.log('removing pin class from right nav'); //console.log('removing pin class from right nav');
$(RightNavPanel).removeClass('pinnedOpen'); $(RightNavPanel).removeClass('pinnedOpen');
if ($(RightNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) { if ($(RightNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {
@@ -584,10 +628,10 @@ $("document").ready(function () {
$(LPanelPin).on("click", function () { $(LPanelPin).on("click", function () {
SaveLocal("LNavLockOn", $(LPanelPin).prop("checked")); SaveLocal("LNavLockOn", $(LPanelPin).prop("checked"));
if ($(LPanelPin).prop("checked") == true) { if ($(LPanelPin).prop("checked") == true) {
console.log('adding pin class to Left nav'); //console.log('adding pin class to Left nav');
$(LeftNavPanel).addClass('pinnedOpen'); $(LeftNavPanel).addClass('pinnedOpen');
} else { } else {
console.log('removing pin class from Left nav'); //console.log('removing pin class from Left nav');
$(LeftNavPanel).removeClass('pinnedOpen'); $(LeftNavPanel).removeClass('pinnedOpen');
if ($(LeftNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) { if ($(LeftNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {
@@ -651,10 +695,7 @@ $("document").ready(function () {
$(AutoLoadChatCheckbox).on("change", function () { SaveLocal("AutoLoadChatEnabled", $(AutoLoadChatCheckbox).prop("checked")); }); $(AutoLoadChatCheckbox).on("change", function () { SaveLocal("AutoLoadChatEnabled", $(AutoLoadChatCheckbox).prop("checked")); });
$(SelectedCharacterTab).click(function () { SaveLocal('SelectedNavTab', 'rm_button_selected_ch'); }); $(SelectedCharacterTab).click(function () { SaveLocal('SelectedNavTab', 'rm_button_selected_ch'); });
$("#rm_button_characters").click(function () { //if char list is clicked, in addition to saving it... $("#rm_button_characters").click(function () { SaveLocal('SelectedNavTab', 'rm_button_characters'); });
SaveLocal('SelectedNavTab', 'rm_button_characters');
characters.sort(Intl.Collator().compare); // we sort the list
});
// 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
$(document).on("click", ".character_select", function () { $(document).on("click", ".character_select", function () {

View File

@@ -160,7 +160,7 @@ async function connectToApi(baseUrl) {
if (getExtensionsResult.ok) { if (getExtensionsResult.ok) {
const data = await getExtensionsResult.json(); const data = await getExtensionsResult.json();
modules = data.modules; modules = data.modules;
activateExtensions(); await activateExtensions();
} }
updateStatus(getExtensionsResult.ok); updateStatus(getExtensionsResult.ok);
@@ -273,12 +273,15 @@ async function loadExtensionSettings(settings) {
} }
$("#extensions_url").val(extension_settings.apiUrl); $("#extensions_url").val(extension_settings.apiUrl);
$("#extensions_autoconnect").prop('checked', extension_settings.autoConnect).trigger('input'); $("#extensions_autoconnect").prop('checked', extension_settings.autoConnect);
// Activate offline extensions // Activate offline extensions
extensionNames = await discoverExtensions(); extensionNames = await discoverExtensions();
manifests = await getManifests(extensionNames) manifests = await getManifests(extensionNames)
activateExtensions(); await activateExtensions();
if (extension_settings.autoConnect && extension_settings.apiUrl) {
await connectToApi(extension_settings.apiUrl);
}
} }
$(document).ready(async function () { $(document).ready(async function () {

View File

@@ -1,5 +1,6 @@
import { callPopup, saveSettingsDebounced } from '../../../script.js' import { callPopup, is_send_press, saveSettingsDebounced } from '../../../script.js'
import { extension_settings, getContext } from '../../extensions.js' import { extension_settings, getContext } from '../../extensions.js'
import { is_group_generating } from '../../group-chats.js'
import { getStringHash } from '../../utils.js' import { getStringHash } from '../../utils.js'
import { ElevenLabsTtsProvider } from './elevenlabs.js' import { ElevenLabsTtsProvider } from './elevenlabs.js'
import { SileroTtsProvider } from './silerotts.js' import { SileroTtsProvider } from './silerotts.js'
@@ -43,6 +44,11 @@ async function moduleWorker() {
return return
} }
// Message is currently being generated
if (is_send_press || is_group_generating) {
return;
}
// Chat/character/group changed // Chat/character/group changed
if ( if (
(context.groupId && lastGroupId !== context.groupId) || (context.groupId && lastGroupId !== context.groupId) ||
@@ -115,7 +121,7 @@ async function playAudioData(audioBlob) {
window['tts_preview'] = function (id) { window['tts_preview'] = function (id) {
const audio = document.getElementById(id) const audio = document.getElementById(id)
if (!audio.hidden) { if (!$(audio).data('disabled')) {
audio.play() audio.play()
} }
else { else {
@@ -131,7 +137,7 @@ async function onTtsVoicesClick() {
for (const voice of voiceIds) { for (const voice of voiceIds) {
popupText += `<div class="voice_preview"><span class="voice_lang">${voice.lang || ''}</span> <b class="voice_name">${voice.name}</b> <i onclick="tts_preview('${voice.voice_id}')" class="fa-solid fa-play"></i></div>` popupText += `<div class="voice_preview"><span class="voice_lang">${voice.lang || ''}</span> <b class="voice_name">${voice.name}</b> <i onclick="tts_preview('${voice.voice_id}')" class="fa-solid fa-play"></i></div>`
popupText += `<audio id="${voice.voice_id}" src="${voice.preview_url}" hidden="${!!voice.preview_url}"></audio>` popupText += `<audio id="${voice.voice_id}" src="${voice.preview_url}" data-disabled="${voice.preview_url == false}"></audio>`
} }
} catch { } catch {
popupText = 'Could not load voices list. Check your API key.' popupText = 'Could not load voices list. Check your API key.'
@@ -235,7 +241,7 @@ async function processTtsQueue() {
console.debug('New message found, running TTS') console.debug('New message found, running TTS')
currentTtsJob = ttsJobQueue.shift() currentTtsJob = ttsJobQueue.shift()
const text = currentTtsJob.mes.replaceAll('*', '...') const text = currentTtsJob.mes.replaceAll('*', '')
const char = currentTtsJob.name const char = currentTtsJob.name
try { try {

View File

@@ -87,7 +87,7 @@ class SystemTtsProvider {
return speechSynthesis return speechSynthesis
.getVoices() .getVoices()
.sort((a, b) => a.lang.localeCompare(b.lang) || a.name.localeCompare(b.name)) .sort((a, b) => a.lang.localeCompare(b.lang) || a.name.localeCompare(b.name))
.map(x => ({ name: x.name, voice_id: x.voiceURI, preview_url: '', lang: x.lang })); .map(x => ({ name: x.name, voice_id: x.voiceURI, preview_url: false, lang: x.lang }));
} }
previewTtsVoice(voiceId) { previewTtsVoice(voiceId) {

View File

@@ -5,7 +5,7 @@ import {
delay, delay,
} from './utils.js'; } from './utils.js';
import { RA_CountCharTokens, humanizedDateTime } from "./RossAscends-mods.js"; import { RA_CountCharTokens, humanizedDateTime } from "./RossAscends-mods.js";
import { sortCharactersList } from './power-user.js'; import { sortCharactersList, sortGroupMembers } from './power-user.js';
import { import {
chat, chat,
@@ -191,6 +191,7 @@ function resetSelectedGroup() {
async function saveGroupChat(groupId, shouldSaveGroup) { async function saveGroupChat(groupId, shouldSaveGroup) {
const group = groups.find(x => x.id == groupId); const group = groups.find(x => x.id == groupId);
const chat_id = group.chat_id; const chat_id = group.chat_id;
group['date_last_chat'] = Date.now();
const response = await fetch("/savegroupchat", { const response = await fetch("/savegroupchat", {
method: "POST", method: "POST",
headers: getRequestHeaders(), headers: getRequestHeaders(),
@@ -200,6 +201,7 @@ async function saveGroupChat(groupId, shouldSaveGroup) {
if (shouldSaveGroup && response.ok) { if (shouldSaveGroup && response.ok) {
await editGroup(groupId); await editGroup(groupId);
} }
sortCharactersList();
} }
export async function renameGroupMember(oldAvatar, newAvatar, newName) { export async function renameGroupMember(oldAvatar, newAvatar, newName) {
@@ -898,7 +900,7 @@ function select_group_chats(groupId, skipAnimation) {
} }
} }
sortCharactersList("#rm_group_add_members .group_member"); sortGroupMembers("#rm_group_add_members .group_member");
filterMembersByFavorites(false); filterMembersByFavorites(false);
const groupHasMembers = !!$("#rm_group_members").children().length; const groupHasMembers = !!$("#rm_group_members").children().length;
@@ -909,9 +911,11 @@ function select_group_chats(groupId, skipAnimation) {
if (groupId) { if (groupId) {
$("#rm_group_submit").hide(); $("#rm_group_submit").hide();
$("#rm_group_delete").show(); $("#rm_group_delete").show();
$("#rm_group_scenario").show();
} else { } else {
$("#rm_group_submit").show(); $("#rm_group_submit").show();
$("#rm_group_delete").hide(); $("#rm_group_delete").hide();
$("#rm_group_scenario").hide();
} }
$("#rm_group_delete").off(); $("#rm_group_delete").off();
@@ -986,7 +990,7 @@ function select_group_chats(groupId, skipAnimation) {
} }
} }
sortCharactersList("#rm_group_add_members .group_member"); sortGroupMembers("#rm_group_add_members .group_member");
}); });
} }
@@ -1192,10 +1196,12 @@ export async function openGroupChat(groupId, chatId) {
group.past_metadata[previousChat] = Object.assign({}, chat_metadata); group.past_metadata[previousChat] = Object.assign({}, chat_metadata);
group.chat_id = chatId; group.chat_id = chatId;
group.chat_metadata = group.past_metadata[chatId] || {}; group.chat_metadata = group.past_metadata[chatId] || {};
group['date_last_chat'] = Date.now();
updateChatMetadata(group.chat_metadata, true); updateChatMetadata(group.chat_metadata, true);
await editGroup(groupId, true); await editGroup(groupId, true);
await getGroupChat(groupId); await getGroupChat(groupId);
sortCharactersList();
} }
export async function renameGroupChat(groupId, oldChatId, newChatId) { export async function renameGroupChat(groupId, oldChatId, newChatId) {
@@ -1264,11 +1270,35 @@ export async function saveGroupBookmarkChat(groupId, name, metadata) {
}); });
} }
function setGroupScenario() {
if (!selected_group) {
return;
}
const template = $('#group_scenario_template .group_scenario').clone();
const metadataValue = chat_metadata['scenario'] || '';
template.find('.group_chat_scenario').text(metadataValue);
callPopup(template.get(0).outerHTML, 'text');
}
function onGroupScenarioInput() {
const value = $(this).val();
const metadata = { scenario: value, };
updateChatMetadata(metadata, false);
}
function onGroupScenarioRemoveClick() {
$(this).closest('.group_scenario').find('.group_chat_scenario').val('').trigger('input');
}
jQuery(() => { jQuery(() => {
$(document).on("click", ".group_select", selectGroup); $(document).on("click", ".group_select", selectGroup);
$(document).on("input", ".group_chat_scenario", onGroupScenarioInput);
$(document).on("click", ".remove_scenario_override", onGroupScenarioRemoveClick);
$("#rm_group_filter").on("input", filterGroupMembers); $("#rm_group_filter").on("input", filterGroupMembers);
$("#group_fav_filter").on("click", toggleFilterByFavorites); $("#group_fav_filter").on("click", toggleFilterByFavorites);
$("#rm_group_submit").on("click", createGroup); $("#rm_group_submit").on("click", createGroup);
$("#rm_group_scenario").on("click", setGroupScenario);
$("#rm_group_automode").on("input", function () { $("#rm_group_automode").on("input", function () {
const value = $(this).prop("checked"); const value = $(this).prop("checked");
is_group_automode_enabled = value; is_group_automode_enabled = value;

View File

@@ -25,6 +25,7 @@ import {
} from "./power-user.js"; } from "./power-user.js";
import { import {
delay,
download, download,
getStringHash, getStringHash,
parseJsonFile, parseJsonFile,
@@ -79,6 +80,7 @@ const default_settings = {
temp_openai: 0.9, temp_openai: 0.9,
freq_pen_openai: 0.7, freq_pen_openai: 0.7,
pres_pen_openai: 0.7, pres_pen_openai: 0.7,
top_p_openai: 1.0,
stream_openai: false, stream_openai: false,
openai_max_context: gpt3_max, openai_max_context: gpt3_max,
openai_max_tokens: 300, openai_max_tokens: 300,
@@ -103,6 +105,7 @@ const oai_settings = {
temp_openai: 1.0, temp_openai: 1.0,
freq_pen_openai: 0, freq_pen_openai: 0,
pres_pen_openai: 0, pres_pen_openai: 0,
top_p_openai: 1.0,
stream_openai: false, stream_openai: false,
openai_max_context: gpt3_max, openai_max_context: gpt3_max,
openai_max_tokens: 300, openai_max_tokens: 300,
@@ -204,9 +207,11 @@ function generateOpenAIPromptCache(charPersonality, topAnchorDepth, anchorTop, b
item = `[${name2} is ${personalityAndAnchor}]\n${item}`; item = `[${name2} is ${personalityAndAnchor}]\n${item}`;
} }
} }
if (i === openai_msgs.length - 1 && openai_msgs.length > bottomAnchorThreshold && $.trim(item).substr(0, (name1 + ":").length) == name1 + ":") {//For add anchor in end if (i === openai_msgs.length - 1 && openai_msgs.length > bottomAnchorThreshold && msg.role === "user") {//For add anchor in end
if (anchorBottom) {
item = anchorBottom + "\n" + item; item = anchorBottom + "\n" + item;
} }
}
msg["content"] = item; msg["content"] = item;
openai_msgs[i] = msg; openai_msgs[i] = msg;
@@ -238,14 +243,14 @@ function parseExampleIntoIndividual(messageExampleString) {
let cur_str = tmp[i]; let cur_str = tmp[i];
// if it's the user message, switch into user mode and out of bot mode // if it's the user message, switch into user mode and out of bot mode
// yes, repeated code, but I don't care // yes, repeated code, but I don't care
if (cur_str.indexOf(name1 + ":") === 0) { if (cur_str.startsWith(name1 + ":")) {
in_user = true; in_user = true;
// we were in the bot mode previously, add the message // we were in the bot mode previously, add the message
if (in_bot) { if (in_bot) {
add_msg(name2, "system", "example_assistant"); add_msg(name2, "system", "example_assistant");
} }
in_bot = false; in_bot = false;
} else if (cur_str.indexOf(name2 + ":") === 0) { } else if (cur_str.startsWith(name2 + ":")) {
in_bot = true; in_bot = true;
// we were in the user mode previously, add the message // we were in the user mode previously, add the message
if (in_user) { if (in_user) {
@@ -306,12 +311,15 @@ async function prepareOpenAIMessages(name2, storyString, worldInfoBefore, worldI
// todo: static value, maybe include in the initial context calculation // todo: static value, maybe include in the initial context calculation
let new_chat_msg = { "role": "system", "content": "[Start a new chat]" }; let new_chat_msg = { "role": "system", "content": "[Start a new chat]" };
let start_chat_count = countTokens([new_chat_msg], true); let start_chat_count = countTokens([new_chat_msg], true);
await delay(1);
let total_count = countTokens([prompt_msg], true) + start_chat_count; let total_count = countTokens([prompt_msg], true) + start_chat_count;
await delay(1);
if (bias && bias.trim().length) { if (bias && bias.trim().length) {
let bias_msg = { "role": "system", "content": bias.trim() }; let bias_msg = { "role": "system", "content": bias.trim() };
openai_msgs.push(bias_msg); openai_msgs.push(bias_msg);
total_count += countTokens([bias_msg], true); total_count += countTokens([bias_msg], true);
await delay(1);
} }
if (selected_group) { if (selected_group) {
@@ -328,11 +336,13 @@ async function prepareOpenAIMessages(name2, storyString, worldInfoBefore, worldI
// add a group nudge count // add a group nudge count
let group_nudge_count = countTokens([group_nudge], true); let group_nudge_count = countTokens([group_nudge], true);
await delay(1);
total_count += group_nudge_count; total_count += group_nudge_count;
// recount tokens for new start message // recount tokens for new start message
total_count -= start_chat_count total_count -= start_chat_count
start_chat_count = countTokens([new_chat_msg], true); start_chat_count = countTokens([new_chat_msg], true);
await delay(1);
total_count += start_chat_count; total_count += start_chat_count;
} }
@@ -341,6 +351,7 @@ async function prepareOpenAIMessages(name2, storyString, worldInfoBefore, worldI
openai_msgs.push(jailbreakMessage); openai_msgs.push(jailbreakMessage);
total_count += countTokens([jailbreakMessage], true); total_count += countTokens([jailbreakMessage], true);
await delay(1);
} }
if (isImpersonate) { if (isImpersonate) {
@@ -348,6 +359,7 @@ async function prepareOpenAIMessages(name2, storyString, worldInfoBefore, worldI
openai_msgs.push(impersonateMessage); openai_msgs.push(impersonateMessage);
total_count += countTokens([impersonateMessage], true); total_count += countTokens([impersonateMessage], true);
await delay(1);
} }
// The user wants to always have all example messages in the context // The user wants to always have all example messages in the context
@@ -370,10 +382,12 @@ async function prepareOpenAIMessages(name2, storyString, worldInfoBefore, worldI
} }
} }
total_count += countTokens(examples_tosend, true); total_count += countTokens(examples_tosend, true);
await delay(1);
// go from newest message to oldest, because we want to delete the older ones from the context // go from newest message to oldest, because we want to delete the older ones from the context
for (let j = openai_msgs.length - 1; j >= 0; j--) { for (let j = openai_msgs.length - 1; j >= 0; j--) {
let item = openai_msgs[j]; let item = openai_msgs[j];
let item_count = countTokens(item, true); let item_count = countTokens(item, true);
await delay(1);
// If we have enough space for this message, also account for the max assistant reply size // If we have enough space for this message, also account for the max assistant reply size
if ((total_count + item_count) < (this_max_context - oai_settings.openai_max_tokens)) { if ((total_count + item_count) < (this_max_context - oai_settings.openai_max_tokens)) {
openai_msgs_tosend.push(item); openai_msgs_tosend.push(item);
@@ -388,6 +402,7 @@ async function prepareOpenAIMessages(name2, storyString, worldInfoBefore, worldI
for (let j = openai_msgs.length - 1; j >= 0; j--) { for (let j = openai_msgs.length - 1; j >= 0; j--) {
let item = openai_msgs[j]; let item = openai_msgs[j];
let item_count = countTokens(item, true); let item_count = countTokens(item, true);
await delay(1);
// If we have enough space for this message, also account for the max assistant reply size // If we have enough space for this message, also account for the max assistant reply size
if ((total_count + item_count) < (this_max_context - oai_settings.openai_max_tokens)) { if ((total_count + item_count) < (this_max_context - oai_settings.openai_max_tokens)) {
openai_msgs_tosend.push(item); openai_msgs_tosend.push(item);
@@ -410,6 +425,7 @@ async function prepareOpenAIMessages(name2, storyString, worldInfoBefore, worldI
// add the block only if there is enough space for all its messages // add the block only if there is enough space for all its messages
const example_count = countTokens(example_block, true); const example_count = countTokens(example_block, true);
await delay(1);
if ((total_count + example_count) < (this_max_context - oai_settings.openai_max_tokens)) { if ((total_count + example_count) < (this_max_context - oai_settings.openai_max_tokens)) {
examples_tosend.push(...example_block) examples_tosend.push(...example_block)
total_count += example_count; total_count += example_count;
@@ -511,6 +527,7 @@ async function sendOpenAIRequest(type, openai_msgs_tosend, signal) {
"temperature": parseFloat(oai_settings.temp_openai), "temperature": parseFloat(oai_settings.temp_openai),
"frequency_penalty": parseFloat(oai_settings.freq_pen_openai), "frequency_penalty": parseFloat(oai_settings.freq_pen_openai),
"presence_penalty": parseFloat(oai_settings.pres_pen_openai), "presence_penalty": parseFloat(oai_settings.pres_pen_openai),
"top_p": parseFloat(oai_settings.top_p_openai),
"max_tokens": oai_settings.openai_max_tokens, "max_tokens": oai_settings.openai_max_tokens,
"stream": stream, "stream": stream,
"reverse_proxy": oai_settings.reverse_proxy, "reverse_proxy": oai_settings.reverse_proxy,
@@ -660,6 +677,7 @@ function loadOpenAISettings(data, settings) {
oai_settings.temp_openai = settings.temp_openai ?? default_settings.temp_openai; oai_settings.temp_openai = settings.temp_openai ?? default_settings.temp_openai;
oai_settings.freq_pen_openai = settings.freq_pen_openai ?? default_settings.freq_pen_openai; oai_settings.freq_pen_openai = settings.freq_pen_openai ?? default_settings.freq_pen_openai;
oai_settings.pres_pen_openai = settings.pres_pen_openai ?? default_settings.pres_pen_openai; oai_settings.pres_pen_openai = settings.pres_pen_openai ?? default_settings.pres_pen_openai;
oai_settings.top_p_openai = settings.top_p_openai ?? default_settings.top_p_openai;
oai_settings.stream_openai = settings.stream_openai ?? default_settings.stream_openai; oai_settings.stream_openai = settings.stream_openai ?? default_settings.stream_openai;
oai_settings.openai_max_context = settings.openai_max_context ?? default_settings.openai_max_context; oai_settings.openai_max_context = settings.openai_max_context ?? default_settings.openai_max_context;
oai_settings.openai_max_tokens = settings.openai_max_tokens ?? default_settings.openai_max_tokens; oai_settings.openai_max_tokens = settings.openai_max_tokens ?? default_settings.openai_max_tokens;
@@ -707,6 +725,9 @@ function loadOpenAISettings(data, settings) {
$('#pres_pen_openai').val(oai_settings.pres_pen_openai); $('#pres_pen_openai').val(oai_settings.pres_pen_openai);
$('#pres_pen_counter_openai').text(Number(oai_settings.pres_pen_openai).toFixed(2)); $('#pres_pen_counter_openai').text(Number(oai_settings.pres_pen_openai).toFixed(2));
$('#top_p_openai').val(oai_settings.top_p_openai);
$('#top_p_counter_openai').text(Number(oai_settings.top_p_openai).toFixed(2));
if (settings.reverse_proxy !== undefined) oai_settings.reverse_proxy = settings.reverse_proxy; if (settings.reverse_proxy !== undefined) oai_settings.reverse_proxy = settings.reverse_proxy;
$('#openai_reverse_proxy').val(oai_settings.reverse_proxy); $('#openai_reverse_proxy').val(oai_settings.reverse_proxy);
@@ -792,6 +813,7 @@ async function saveOpenAIPreset(name, settings) {
temperature: settings.temp_openai, temperature: settings.temp_openai,
frequency_penalty: settings.freq_pen_openai, frequency_penalty: settings.freq_pen_openai,
presence_penalty: settings.pres_pen_openai, presence_penalty: settings.pres_pen_openai,
top_p: settings.top_p_openai,
openai_max_context: settings.openai_max_context, openai_max_context: settings.openai_max_context,
openai_max_tokens: settings.openai_max_tokens, openai_max_tokens: settings.openai_max_tokens,
nsfw_toggle: settings.nsfw_toggle, nsfw_toggle: settings.nsfw_toggle,
@@ -1056,6 +1078,7 @@ function onSettingsPresetChange() {
temperature: ['#temp_openai', 'temp_openai', false], temperature: ['#temp_openai', 'temp_openai', false],
frequency_penalty: ['#freq_pen_openai', 'freq_pen_openai', false], frequency_penalty: ['#freq_pen_openai', 'freq_pen_openai', false],
presence_penalty: ['#pres_pen_openai', 'pres_pen_openai', false], presence_penalty: ['#pres_pen_openai', 'pres_pen_openai', false],
top_p: ['#top_p_openai', 'top_p_openai', false],
openai_model: ['#model_openai_select', 'openai_model', false], openai_model: ['#model_openai_select', 'openai_model', false],
openai_max_context: ['#openai_max_context', 'openai_max_context', false], openai_max_context: ['#openai_max_context', 'openai_max_context', false],
openai_max_tokens: ['#openai_max_tokens', 'openai_max_tokens', false], openai_max_tokens: ['#openai_max_tokens', 'openai_max_tokens', false],
@@ -1160,6 +1183,13 @@ $(document).ready(function () {
}); });
$(document).on('input', '#top_p_openai', function () {
oai_settings.top_p_openai = $(this).val();
$('#top_p_counter_openai').text(Number($(this).val()).toFixed(2));
saveSettingsDebounced();
});
$(document).on('input', '#openai_max_context', function () { $(document).on('input', '#openai_max_context', function () {
oai_settings.openai_max_context = parseInt($(this).val()); oai_settings.openai_max_context = parseInt($(this).val());
$('#openai_max_context_counter').text(`${$(this).val()}`); $('#openai_max_context_counter').text(`${$(this).val()}`);

View File

@@ -8,11 +8,15 @@ import {
reloadCurrentChat, reloadCurrentChat,
getRequestHeaders, getRequestHeaders,
} from "../script.js"; } from "../script.js";
import {
groups,
} from "./group-chats.js";
export { export {
loadPowerUserSettings, loadPowerUserSettings,
collapseNewlines, collapseNewlines,
playMessageSound, playMessageSound,
sortGroupMembers,
sortCharactersList, sortCharactersList,
fixMarkdown, fixMarkdown,
power_user, power_user,
@@ -57,6 +61,7 @@ const send_on_enter_options = {
let power_user = { let power_user = {
tokenizer: tokenizers.CLASSIC, tokenizer: tokenizers.CLASSIC,
token_padding: 64,
collapse_newlines: false, collapse_newlines: false,
pygmalion_formatting: pygmalion_options.AUTO, pygmalion_formatting: pygmalion_options.AUTO,
pin_examples: false, pin_examples: false,
@@ -100,6 +105,9 @@ let power_user = {
auto_fix_generated_markdown: true, auto_fix_generated_markdown: true,
send_on_enter: send_on_enter_options.AUTO, send_on_enter: send_on_enter_options.AUTO,
render_formulas: false, render_formulas: false,
allow_name2_display: false,
hotswap_enabled: true,
timer_enabled: true,
}; };
let themes = []; let themes = [];
@@ -123,6 +131,9 @@ const storage_keys = {
waifuMode: "TavernAI_waifuMode", waifuMode: "TavernAI_waifuMode",
movingUI: "TavernAI_movingUI", movingUI: "TavernAI_movingUI",
noShadows: "TavernAI_noShadows", noShadows: "TavernAI_noShadows",
hotswap_enabled: 'HotswapEnabled',
timer_enabled: 'TimerEnabled',
}; };
let browser_has_focus = true; let browser_has_focus = true;
@@ -179,6 +190,18 @@ function fixMarkdown(text) {
return newText; return newText;
} }
function switchHotswap() {
const value = localStorage.getItem(storage_keys.hotswap_enabled);
power_user.hotswap_enabled = value === null ? true : value == "true";
$("body").toggleClass("no-hotswap", !power_user.hotswap_enabled);
}
function switchTimer() {
const value = localStorage.getItem(storage_keys.timer_enabled);
power_user.timer_enabled = value === null ? true : value == "true";
$("body").toggleClass("no-timer", !power_user.timer_enabled);
}
function switchUiMode() { function switchUiMode() {
const fastUi = localStorage.getItem(storage_keys.fast_ui_mode); const fastUi = localStorage.getItem(storage_keys.fast_ui_mode);
power_user.fast_ui_mode = fastUi === null ? true : fastUi == "true"; power_user.fast_ui_mode = fastUi === null ? true : fastUi == "true";
@@ -321,6 +344,8 @@ applyChatDisplay();
switchWaifuMode() switchWaifuMode()
switchMovingUI(); switchMovingUI();
noShadows(); noShadows();
switchHotswap();
switchTimer();
function loadPowerUserSettings(settings, data) { function loadPowerUserSettings(settings, data) {
// Load from settings.json // Load from settings.json
@@ -337,10 +362,14 @@ function loadPowerUserSettings(settings, data) {
const waifuMode = localStorage.getItem(storage_keys.waifuMode); const waifuMode = localStorage.getItem(storage_keys.waifuMode);
const movingUI = localStorage.getItem(storage_keys.movingUI); const movingUI = localStorage.getItem(storage_keys.movingUI);
const noShadows = localStorage.getItem(storage_keys.noShadows); const noShadows = localStorage.getItem(storage_keys.noShadows);
const hotswap = localStorage.getItem(storage_keys.hotswap_enabled);
const timer = localStorage.getItem(storage_keys.timer_enabled);
power_user.fast_ui_mode = fastUi === null ? true : fastUi == "true"; power_user.fast_ui_mode = fastUi === null ? true : fastUi == "true";
power_user.waifuMode = waifuMode === null ? false : waifuMode == "true"; power_user.waifuMode = waifuMode === null ? false : waifuMode == "true";
power_user.movingUI = movingUI === null ? false : movingUI == "true"; power_user.movingUI = movingUI === null ? false : movingUI == "true";
power_user.noShadows = noShadows === null ? false : noShadows == "true"; power_user.noShadows = noShadows === null ? false : noShadows == "true";
power_user.hotswap_enabled = hotswap === null ? true : hotswap == "true";
power_user.timer_enabled = timer === null ? true : timer == "true";
power_user.avatar_style = Number(localStorage.getItem(storage_keys.avatar_style) ?? avatar_styles.ROUND); power_user.avatar_style = Number(localStorage.getItem(storage_keys.avatar_style) ?? avatar_styles.ROUND);
power_user.chat_display = Number(localStorage.getItem(storage_keys.chat_display) ?? chat_styles.DEFAULT); power_user.chat_display = Number(localStorage.getItem(storage_keys.chat_display) ?? chat_styles.DEFAULT);
power_user.sheld_width = Number(localStorage.getItem(storage_keys.sheld_width) ?? sheld_width.DEFAULT); power_user.sheld_width = Number(localStorage.getItem(storage_keys.sheld_width) ?? sheld_width.DEFAULT);
@@ -372,9 +401,13 @@ function loadPowerUserSettings(settings, data) {
$("#play_message_sound").prop("checked", power_user.play_message_sound); $("#play_message_sound").prop("checked", power_user.play_message_sound);
$("#play_sound_unfocused").prop("checked", power_user.play_sound_unfocused); $("#play_sound_unfocused").prop("checked", power_user.play_sound_unfocused);
$("#auto_save_msg_edits").prop("checked", power_user.auto_save_msg_edits); $("#auto_save_msg_edits").prop("checked", power_user.auto_save_msg_edits);
$("#allow_name2_display").prop("checked", power_user.allow_name2_display);
$("#hotswapEnabled").prop("checked", power_user.hotswap_enabled);
$("#messageTimerEnabled").prop("checked", power_user.timer_enabled);
$(`input[name="avatar_style"][value="${power_user.avatar_style}"]`).prop("checked", true); $(`input[name="avatar_style"][value="${power_user.avatar_style}"]`).prop("checked", true);
$(`input[name="chat_display"][value="${power_user.chat_display}"]`).prop("checked", true); $(`input[name="chat_display"][value="${power_user.chat_display}"]`).prop("checked", true);
$(`input[name="sheld_width"][value="${power_user.sheld_width}"]`).prop("checked", true); $(`input[name="sheld_width"][value="${power_user.sheld_width}"]`).prop("checked", true);
$("#token_padding").val(power_user.token_padding);
$("#font_scale").val(power_user.font_scale); $("#font_scale").val(power_user.font_scale);
$("#font_scale_counter").text(power_user.font_scale); $("#font_scale_counter").text(power_user.font_scale);
@@ -405,7 +438,6 @@ function loadPowerUserSettings(settings, data) {
reloadMarkdownProcessor(power_user.render_formulas); reloadMarkdownProcessor(power_user.render_formulas);
} }
function sortCharactersList(selector = '.character_select') {
const sortFunc = (a, b) => power_user.sort_order == 'asc' ? compareFunc(a, b) : compareFunc(b, a); const sortFunc = (a, b) => power_user.sort_order == 'asc' ? compareFunc(a, b) : compareFunc(b, a);
const compareFunc = (first, second) => { const compareFunc = (first, second) => {
switch (power_user.sort_rule) { switch (power_user.sort_rule) {
@@ -418,6 +450,34 @@ function sortCharactersList(selector = '.character_select') {
} }
}; };
function sortCharactersList() {
const arr1 = groups.map(x => ({
item: x,
id: x.id,
selector: '.group_select',
attribute: 'grid',
}))
const arr2 = characters.map((x, index) => ({
item: x,
id: index,
selector: '.character_select',
attribute: 'chid',
}));
const array = [...arr1, ...arr2];
if (power_user.sort_field == undefined || array.length === 0) {
return;
}
let orderedList = array.slice().sort((a, b) => sortFunc(a.item, b.item));
for (const item of array) {
$(`${item.selector}[${item.attribute}="${item.id}"]`).css({ 'order': orderedList.indexOf(item) });
}
}
function sortGroupMembers(selector) {
if (power_user.sort_field == undefined || characters.length === 0) { if (power_user.sort_field == undefined || characters.length === 0) {
return; return;
} }
@@ -747,6 +807,31 @@ $(document).ready(() => {
saveSettingsDebounced(); saveSettingsDebounced();
}) })
$("#allow_name2_display").on("input", function () {
power_user.allow_name2_display = !!$(this).prop('checked');
reloadCurrentChat();
saveSettingsDebounced();
});
$("#token_padding").on("input", function () {
power_user.token_padding = Number($(this).val());
saveSettingsDebounced();
});
$("#messageTimerEnabled").on("input", function () {
const value = !!$(this).prop('checked');
power_user.timer_enabled = value;
localStorage.setItem(storage_keys.timer_enabled, power_user.timer_enabled);
switchTimer();
});
$("#hotswapEnabled").on("input", function () {
const value = !!$(this).prop('checked');
power_user.hotswap_enabled = value;
localStorage.setItem(storage_keys.hotswap_enabled, power_user.hotswap_enabled);
switchHotswap();
});
$(window).on('focus', function () { $(window).on('focus', function () {
browser_has_focus = true; browser_has_focus = true;
}); });

View File

@@ -558,12 +558,72 @@ code {
gap: 5px; gap: 5px;
} }
.avatar { .avatar {
width: 50px; width: 50px;
height: 50px; height: 50px;
border-style: none; border-style: none;
} }
.mes .avatar {
cursor: pointer;
}
.hotswap {
top: -5px;
}
.hotswapAvatar,
.hotswapAvatar .avatar {
width: 50px !important;
height: 50px !important;
border-style: none;
}
.hotswapAvatar {
opacity: 0.5;
transition: 250ms;
overflow: hidden;
padding: 0 !important;
order: 100;
}
.hotswapAvatar:hover {
opacity: 1;
background-color: transparent !important;
cursor: pointer;
}
.hotswapAvatar .avatar_collage,
.hotswapAvatar.group_select {
border-radius: 50% !important;
position: relative;
overflow: hidden;
min-width: 50px !important;
}
.hotswapAvatar.group_select .avatar img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
border: 1px solid var(--black30a);
/* border-radius: 10px; */
}
.hotswapAvatar .avatar {
width: 50px !important;
height: 50px !important;
object-fit: cover;
object-position: center center;
border-radius: 50% !important;
/* border: 1px solid var(--black30a); */
box-shadow: 0 0 5px var(--black50a);
}
.hotswapAvatar img,
.avatar img { .avatar img {
width: 50px; width: 50px;
height: 50px; height: 50px;
@@ -574,6 +634,14 @@ code {
box-shadow: 0 0 5px var(--black50a); box-shadow: 0 0 5px var(--black50a);
} }
body.no-hotswap .hotswap {
display: none !important;
}
body.no-timer .mes_timer {
display: none !important;
}
body.big-avatars .avatar { body.big-avatars .avatar {
width: 60px; width: 60px;
height: 90px; height: 90px;
@@ -1857,6 +1925,7 @@ input[type='checkbox']:not(#nav-toggle):not(#rm_button_panel_pin) {
background-color: white; background-color: white;
box-shadow: inset 0 0 3px 0 var(--black70a); box-shadow: inset 0 0 3px 0 var(--black70a);
cursor: pointer; cursor: pointer;
flex-shrink: 0;
} }
/* the checkbox starts with a size 0 background of a checkmark */ /* the checkbox starts with a size 0 background of a checkmark */
@@ -2620,10 +2689,11 @@ body .ui-widget-content li:hover {
/* GROUP CHATS */ /* GROUP CHATS */
#rm_group_top_bar { #rm_group_top_bar {
display: flex; /* display: flex;
flex-direction: row; flex-direction: row;
width: 100%; width: 100%;
column-gap: 5px; column-gap: 5px;
justify-content: space-evenly; */
} }
#rm_button_group_chats h2 { #rm_button_group_chats h2 {
@@ -2639,10 +2709,11 @@ body .ui-widget-content li:hover {
#rm_group_chats_block { #rm_group_chats_block {
display: none; display: none;
height: calc(100% - 45px); /* height: calc(100% - 45px);
flex-direction: column; flex-direction: column; */
align-items: flex-start; align-items: flex-start;
padding: 0 5px; padding: 0 5px;
overflow-y: auto;
} }
#rm_group_chats_block h3, #rm_group_chats_block h3,
@@ -2652,13 +2723,13 @@ body .ui-widget-content li:hover {
} }
#rm_group_buttons { #rm_group_buttons {
display: flex; /* display: flex;
flex-direction: row; flex-direction: row;
width: 100%; width: 100%;
align-items: center; align-items: center;
column-gap: 10px; column-gap: 10px;
flex-wrap: wrap; flex-wrap: wrap;
padding: 0 5px; padding: 0 5px; */
} }
#rm_group_buttons>div { #rm_group_buttons>div {
@@ -2689,13 +2760,6 @@ body .ui-widget-content li:hover {
#rm_group_add_members { #rm_group_add_members {
margin-top: 0.25rem; margin-top: 0.25rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
width: 100%;
flex: 1;
max-height: 40%;
min-height: 40%;
overflow: auto;
display: flex;
flex-direction: column;
border: 1px solid grey; border: 1px solid grey;
border-radius: 10px; border-radius: 10px;
background-color: var(--black30a); background-color: var(--black30a);
@@ -2755,10 +2819,11 @@ body .ui-widget-content li:hover {
} }
.group_member_icon { .group_member_icon {
margin: 0 10px;
display: flex; display: flex;
column-gap: 10px; column-gap: 10px;
align-items: center; align-items: center;
justify-content: end;
flex-grow: 1;
} }
.group_member { .group_member {
@@ -3341,7 +3406,7 @@ label[for="extensions_autoconnect"] {
} }
.inline-drawer { .inline-drawer {
padding-bottom: 10px; /* padding-bottom: 10px; */
} }
.code-copy { .code-copy {
@@ -3392,6 +3457,7 @@ label[for="extensions_autoconnect"] {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 5px 0;
} }
.inline-drawer-content { .inline-drawer-content {
@@ -3417,7 +3483,7 @@ label[for="extensions_autoconnect"] {
position: absolute; position: absolute;
left: 0; left: 0;
right: 0; right: 0;
max-width: var(--sheldWidth); /* max-width: var(--sheldWidth); */
margin: 35px auto 0 auto; margin: 35px auto 0 auto;
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)));
-webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength)));
@@ -3479,10 +3545,6 @@ toolcool-color-picker {
flex-wrap: nowrap; flex-wrap: nowrap;
} }
.flex1 {
flex: 1;
}
.alignitemscenter { .alignitemscenter {
align-items: center; align-items: center;
} }
@@ -3631,7 +3693,8 @@ toolcool-color-picker {
} }
.openai_restorable, .openai_restorable,
.poe_restorable { .poe_restorable,
.title_restorable {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
@@ -3841,6 +3904,51 @@ body.waifuMode #avatar_zoom_popup {
object-fit: cover; object-fit: cover;
} }
.debug-red {
border: 1px solid red !important;
}
.debug-yellow {
border: 1px solid yellow !important;
}
.debug-green {
border: 1px solid green !important;
}
.debug-blue {
border: 1px solid blue !important;
}
.debug-purple {
border: 1px solid purple !important;
}
.fontsize80p {
font-size: calc(var(--mainFontSize) * 0.8) !important;
}
.fontsize60p {
font-size: calc(var(--mainFontSize) * 0.6) !important;
}
.paddingTopBot5 {
padding: 5px 0;
}
.paddingLeftRight5 {
padding: 0 5px;
}
.heightFitContent {
height: fit-content;
}
.flexGap5 {
gap: 5px;
}
/* ---------- @media queries must always go at the bottom ------------*/ /* ---------- @media queries must always go at the bottom ------------*/
/*will apply to anything 1000px or less. this catches ipads, horizontal phones, and vertical phones)*/ /*will apply to anything 1000px or less. this catches ipads, horizontal phones, and vertical phones)*/

View File

@@ -1806,10 +1806,36 @@ app.post('/getgroups', jsonParser, (_, response) => {
} }
const files = fs.readdirSync(directories.groups); const files = fs.readdirSync(directories.groups);
const chats = fs.readdirSync(directories.groupChats);
files.forEach(function (file) { files.forEach(function (file) {
const fileContents = fs.readFileSync(path.join(directories.groups, file), 'utf8'); try {
const filePath = path.join(directories.groups, file);
const fileContents = fs.readFileSync(filePath, 'utf8');
const group = json5.parse(fileContents); const group = json5.parse(fileContents);
const groupStat = fs.statSync(filePath);
group['date_added'] = groupStat.birthtimeMs;
let chat_size = 0;
let date_last_chat = 0;
if (Array.isArray(group.chats) && Array.isArray(chats)) {
for (const chat of chats) {
if (group.chats.includes(path.parse(chat).name)) {
const chatStat = fs.statSync(path.join(directories.groupChats, chat));
chat_size += chatStat.size;
date_last_chat = Math.max(date_last_chat, chatStat.mtimeMs);
}
}
}
group['date_last_chat'] = date_last_chat;
group['chat_size'] = chat_size;
groups.push(group); groups.push(group);
}
catch (error) {
console.error(error);
}
}); });
return response.send(groups); return response.send(groups);
@@ -2350,6 +2376,7 @@ app.post("/generate_openai", jsonParser, function (request, response_generate_op
"stream": request.body.stream, "stream": request.body.stream,
"presence_penalty": request.body.presence_penalty, "presence_penalty": request.body.presence_penalty,
"frequency_penalty": request.body.frequency_penalty, "frequency_penalty": request.body.frequency_penalty,
"top_p": request.body.top_p,
"stop": request.body.stop, "stop": request.body.stop,
"logit_bias": request.body.logit_bias "logit_bias": request.body.logit_bias
}, },