mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'dev' into dev
This commit is contained in:
@ -104,7 +104,7 @@
|
|||||||
<div id="lm_button_panel_pin_div" title="Locked = AI Configuration panel will stay open">
|
<div id="lm_button_panel_pin_div" title="Locked = AI Configuration panel will stay open">
|
||||||
<input type="checkbox" id="lm_button_panel_pin">
|
<input type="checkbox" id="lm_button_panel_pin">
|
||||||
<label for="lm_button_panel_pin">
|
<label for="lm_button_panel_pin">
|
||||||
<div class="unchecked fa-solid fa-lock-open "></div>
|
<div class="unchecked fa-solid fa-unlock "></div>
|
||||||
<div class="checked fa-solid fa-lock "></div>
|
<div class="checked fa-solid fa-lock "></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@ -116,7 +116,7 @@
|
|||||||
<div id="respective-presets-block" class="width100p">
|
<div id="respective-presets-block" class="width100p">
|
||||||
<div id="kobold_api-presets">
|
<div id="kobold_api-presets">
|
||||||
<h3><span data-i18n="kobldpresets">Kobold Presets</span>
|
<h3><span data-i18n="kobldpresets">Kobold Presets</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#koboldai" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/api-connections/koboldai/" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
@ -127,7 +127,7 @@
|
|||||||
<div id="novel_api-presets">
|
<div id="novel_api-presets">
|
||||||
<h3>
|
<h3>
|
||||||
<span data-i18n="novelaipreserts">NovelAI Presets</span>
|
<span data-i18n="novelaipreserts">NovelAI Presets</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#novelai" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/api-connections/novelai/" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
@ -340,7 +340,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="range-block-range-and-counter">
|
<div class="range-block-range-and-counter">
|
||||||
<div class="range-block-range">
|
<div class="range-block-range">
|
||||||
<input type="range" id="rep_pen_slope_novel" name="volume" min="0" max="10" step="0.01">
|
<input type="range" id="rep_pen_slope_novel" name="volume" min="0.01" max="10" step="0.01">
|
||||||
</div>
|
</div>
|
||||||
<div class="range-block-counter">
|
<div class="range-block-counter">
|
||||||
<div contenteditable="true" data-for="rep_pen_slope_novel" id="rep_pen_slope_counter_novel">
|
<div contenteditable="true" data-for="rep_pen_slope_novel" id="rep_pen_slope_counter_novel">
|
||||||
@ -625,6 +625,12 @@
|
|||||||
Use "Unlocked Context" to enable chunked generation.
|
Use "Unlocked Context" to enable chunked generation.
|
||||||
It extends the context window in exchange for reply generation speed.
|
It extends the context window in exchange for reply generation speed.
|
||||||
</div>
|
</div>
|
||||||
|
<h4>Safe Context Size values for Poe bots:</h4>
|
||||||
|
<ul class="margin0auto">
|
||||||
|
<li>ChatGPT / Sage = 3600-4000 tokens</li>
|
||||||
|
<li>Claude-instant / Claude+ = 5000-5500 tokens</li>
|
||||||
|
<li>GPT-4 = 7600-8000 tokens</li>
|
||||||
|
</ul>
|
||||||
<div class="flex-container spaceEvenly">
|
<div class="flex-container spaceEvenly">
|
||||||
<div id="poe_send_jailbreak" class="menu_button widthFitContent" title="Attempts to automatically jailbreak the bot">
|
<div id="poe_send_jailbreak" class="menu_button widthFitContent" title="Attempts to automatically jailbreak the bot">
|
||||||
Send Jailbreak
|
Send Jailbreak
|
||||||
@ -1293,12 +1299,12 @@
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
<h4>API key</h4>
|
<h4>API key</h4>
|
||||||
<h5>Get it here: <a target="_blank" href="https://horde.koboldai.net/register">Register</a><br>
|
<small>Get it here: <a target="_blank" href="https://horde.koboldai.net/register">Register</a> (<a id="horde_kudos" href="javascript:void(0);">View my Kudos</a>)<br>
|
||||||
Enter <span class="monospace">0000000000</span> to use anonymous mode.
|
Enter <span class="monospace">0000000000</span> to use anonymous mode.
|
||||||
</h5>
|
</small>
|
||||||
<div>
|
<!-- <div>
|
||||||
<a id="horde_kudos" href="javascript:void(0);">View my Kudos</a>
|
<a id="horde_kudos" href="javascript:void(0);">View my Kudos</a>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<input id="horde_api_key" name="horde_api_key" class="text_pole flex1" maxlength="500" type="text" placeholder="0000000000" autocomplete="off">
|
<input id="horde_api_key" name="horde_api_key" class="text_pole flex1" maxlength="500" type="text" placeholder="0000000000" autocomplete="off">
|
||||||
<div title="Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_horde"></div>
|
<div title="Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_horde"></div>
|
||||||
@ -1312,7 +1318,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</h4>
|
</h4>
|
||||||
<small class="horde_multiple_hint">You can select multiple models.<br>Avoid sending
|
<small class="horde_multiple_hint">You can select multiple models.<br>Avoid sending
|
||||||
sensitive information to the Horde. <a id="horde_privacy_disclaimer" target="_blank" href="https://docs.sillytavern.app/usage/guidebook/#horde">Learn more</a></small>
|
sensitive information to the Horde. <a id="horde_privacy_disclaimer" target="_blank" href="https://docs.sillytavern.app/usage/api-connections/koboldai/">Learn more</a></small>
|
||||||
<select id="horde_model" multiple>
|
<select id="horde_model" multiple>
|
||||||
<option>-- Horde models not loaded --</option>
|
<option>-- Horde models not loaded --</option>
|
||||||
</select>
|
</select>
|
||||||
@ -1327,7 +1333,7 @@
|
|||||||
<form action="javascript:void(null);" method="post" enctype="multipart/form-data">
|
<form action="javascript:void(null);" method="post" enctype="multipart/form-data">
|
||||||
<div id="kobold_api_block">
|
<div id="kobold_api_block">
|
||||||
<h4>API url</h4>
|
<h4>API url</h4>
|
||||||
<h5>Example: http://127.0.0.1:5000/api </h5>
|
<small>Example: http://127.0.0.1:5000/api </small>
|
||||||
<input id="api_url_text" name="api_url" class="text_pole" placeholder="http://127.0.0.1:5000/api" maxlength="500" value="" autocomplete="off">
|
<input id="api_url_text" name="api_url" class="text_pole" placeholder="http://127.0.0.1:5000/api" maxlength="500" value="" autocomplete="off">
|
||||||
<input id="api_button" class="menu_button" type="submit" value="Connect">
|
<input id="api_button" class="menu_button" type="submit" value="Connect">
|
||||||
<div id="api_loading" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
|
<div id="api_loading" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
|
||||||
@ -1345,9 +1351,7 @@
|
|||||||
<span>
|
<span>
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
<span data-i18n="Follow">Follow</span> <a href="https://docs.sillytavern.app/usage/guidebook/#api-key" class="notes-link" target="_blank"> <span data-i18n="these directions">these
|
<a href="https://docs.sillytavern.app/usage/api-connections/novelai/" class="notes-link" target="_blank"> <span data-i18n="Get your NovelAI API Key">Get your NovelAI API key</span></a>
|
||||||
directions</span> </a> <span data-i18n="to get your NovelAI API key.">to
|
|
||||||
get your NovelAI API key.</span>
|
|
||||||
</li>
|
</li>
|
||||||
<li><span data-i18n="Enter it in the box below">Enter it in the box below:</span>
|
<li><span data-i18n="Enter it in the box below">Enter it in the box below:</span>
|
||||||
</li>
|
</li>
|
||||||
@ -1363,7 +1367,7 @@
|
|||||||
<input id="api_button_novel" class="menu_button" type="submit" value="Connect">
|
<input id="api_button_novel" class="menu_button" type="submit" value="Connect">
|
||||||
<div id="api_loading_novel" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
|
<div id="api_loading_novel" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
|
||||||
<h4><span data-i18n="Novel AI Model">Novel AI Model</span>
|
<h4><span data-i18n="Novel AI Model">Novel AI Model</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#models" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/api-connections/novelai/#models" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
@ -1379,7 +1383,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="textgenerationwebui_api" style="display: none;position: relative;">
|
<div id="textgenerationwebui_api" style="display: none;position: relative;">
|
||||||
<div class="oobabooga_logo flex-container">
|
<div class="flex-container">
|
||||||
<a href="https://github.com/oobabooga/text-generation-webui" target="_blank">
|
<a href="https://github.com/oobabooga/text-generation-webui" target="_blank">
|
||||||
oobabooga/text-generation-webui
|
oobabooga/text-generation-webui
|
||||||
</a>
|
</a>
|
||||||
@ -1388,15 +1392,15 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex-container">
|
<div class="flex-container flexFlowColumn">
|
||||||
<div class="flex1">
|
<div class="flex1">
|
||||||
<h4 data-i18n="Blocking API url">Blocking API url</h4>
|
<h4 data-i18n="Blocking API url">Blocking API url</h4>
|
||||||
<h5>Example: http://127.0.0.1:5000/</h5>
|
<small>Example: http://127.0.0.1:5000/</small>
|
||||||
<input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
|
<input id="textgenerationwebui_api_url_text" name="textgenerationwebui_api_url" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
<div class="flex1">
|
<div class="flex1">
|
||||||
<h4 data-i18n="Streaming API url">Streaming API url</h4>
|
<h4 data-i18n="Streaming API url">Streaming API url</h4>
|
||||||
<h5>Example: ws://127.0.0.1:5005/api/v1/stream</h5>
|
<small>Example: ws://127.0.0.1:5005/api/v1/stream</small>
|
||||||
<input id="streaming_url_textgenerationwebui" type="text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
|
<input id="streaming_url_textgenerationwebui" type="text" class="text_pole wide100p" maxlength="500" value="" autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1422,7 +1426,7 @@
|
|||||||
<span>
|
<span>
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
Follow<a href="https://docs.sillytavern.app/usage/guidebook/#api-key-1" class="notes-link" target="_blank"> these directions </a> to get your OpenAI
|
Follow<a href="https://docs.sillytavern.app/usage/api-connections/openai/" class="notes-link" target="_blank"> these directions </a> to get your OpenAI
|
||||||
API key.
|
API key.
|
||||||
</li>
|
</li>
|
||||||
<li>Enter it in the box below:</li>
|
<li>Enter it in the box below:</li>
|
||||||
@ -1521,7 +1525,7 @@
|
|||||||
<span>
|
<span>
|
||||||
<ol>
|
<ol>
|
||||||
<li>
|
<li>
|
||||||
Follow <a href="https://docs.sillytavern.app/usage/guidebook/#api-key-2" class="notes-link" target="_blank">these directions</a> to get your 'p-b cookie'
|
Follow <a href="https://docs.sillytavern.app/usage/api-connections/poe/" class="notes-link" target="_blank">these directions</a> to get your 'p-b cookie'
|
||||||
</li>
|
</li>
|
||||||
<li>Enter it in the box below:</li>
|
<li>Enter it in the box below:</li>
|
||||||
</ol>
|
</ol>
|
||||||
@ -1570,7 +1574,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="drawer-content">
|
<div class="drawer-content">
|
||||||
<h3>Advanced Formatting
|
<h3>Advanced Formatting
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#advanced-formatting" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
@ -1616,7 +1620,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h4 data-i18n="Instruct mode">Instruct mode
|
<h4 data-i18n="Instruct mode">Instruct mode
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#instruct-mode" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/instructmode/" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
@ -1693,7 +1697,7 @@
|
|||||||
<h4><span data-i18n="Context Formatting">Context Formatting</span></h4>
|
<h4><span data-i18n="Context Formatting">Context Formatting</span></h4>
|
||||||
<div>
|
<div>
|
||||||
<h4><span data-i18n="Tokenizer">Tokenizer</span>
|
<h4><span data-i18n="Tokenizer">Tokenizer</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#tokenizer" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/#tokenizer" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
@ -1709,7 +1713,7 @@
|
|||||||
<div class="range-block">
|
<div class="range-block">
|
||||||
<div class="range-block-title justifyLeft">
|
<div class="range-block-title justifyLeft">
|
||||||
Token Padding
|
Token Padding
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#token-padding" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/#token-padding" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -1772,7 +1776,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<h4>
|
<h4>
|
||||||
<span data-i18n="Multigen">Multigen</span>
|
<span data-i18n="Multigen">Multigen</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#multigen" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/advancedformatting/#multigen" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
@ -1807,14 +1811,14 @@
|
|||||||
<div id="WI_panel_pin_div" title="Locked = World Editor will stay open">
|
<div id="WI_panel_pin_div" title="Locked = World Editor will stay open">
|
||||||
<input type="checkbox" id="WI_panel_pin">
|
<input type="checkbox" id="WI_panel_pin">
|
||||||
<label for="WI_panel_pin">
|
<label for="WI_panel_pin">
|
||||||
<div class="unchecked fa-solid fa-lock-open "></div>
|
<div class="unchecked fa-solid fa-unlock "></div>
|
||||||
<div class="checked fa-solid fa-lock "></div>
|
<div class="checked fa-solid fa-lock "></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="wi-holder">
|
<div id="wi-holder" class="margin5">
|
||||||
<h3>
|
<h3>
|
||||||
World Info / Lorebooks
|
World Info / Lorebooks
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#world-info" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/worldinfo/" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
@ -1832,39 +1836,40 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-container alignitemscenter">
|
<div class="flex-container alignitemscenter">
|
||||||
<div class="flex1 range-block">
|
<div name="WIScanAndTokens" class="flex1 flex-container flexFlowColumn">
|
||||||
<div class="range-block-title">
|
<div class="flex1 range-block">
|
||||||
<span data-i18n="Scan Depth">Scan Depth</span>
|
<div class="range-block-title">
|
||||||
</div>
|
<span data-i18n="Scan Depth">Scan Depth</span>
|
||||||
<div class="range-block-range-and-counter">
|
|
||||||
<div class="range-block-range">
|
|
||||||
<input type="range" id="world_info_depth" name="volume" min="1" max="10" step="1">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="range-block-counter">
|
<div class="range-block-range-and-counter">
|
||||||
<div contenteditable="true" data-for="world_info_depth" id="world_info_depth_counter">
|
<div class="range-block-range">
|
||||||
depth
|
<input type="range" id="world_info_depth" name="volume" min="1" max="10" step="1">
|
||||||
|
</div>
|
||||||
|
<div class="range-block-counter">
|
||||||
|
<div contenteditable="true" data-for="world_info_depth" id="world_info_depth_counter">
|
||||||
|
depth
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex1 range-block">
|
||||||
|
<div class="range-block-title">
|
||||||
|
<span data-i18n="Token Budget">Token Budget</span>
|
||||||
|
</div>
|
||||||
|
<div class="range-block-range-and-counter">
|
||||||
|
<div class="range-block-range">
|
||||||
|
<input type="range" id="world_info_budget" name="volume" min="32" max="8192" step="1">
|
||||||
|
</div>
|
||||||
|
<div class="range-block-counter">
|
||||||
|
<div contenteditable="true" data-for="world_info_budget" id="world_info_budget_counter">
|
||||||
|
budget
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="range-block flex-container flexFlowColumn">
|
||||||
<div class="flex1 range-block">
|
|
||||||
<div class="range-block-title">
|
|
||||||
<span data-i18n="Token Budget">Token Budget</span>
|
|
||||||
</div>
|
|
||||||
<div class="range-block-range-and-counter">
|
|
||||||
<div class="range-block-range">
|
|
||||||
<input type="range" id="world_info_budget" name="volume" min="32" max="8192" step="1">
|
|
||||||
</div>
|
|
||||||
<div class="range-block-counter">
|
|
||||||
<div contenteditable="true" data-for="world_info_budget" id="world_info_budget_counter">
|
|
||||||
budget
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex1 range-block flex-container">
|
|
||||||
<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" />
|
||||||
<span>
|
<span>
|
||||||
@ -1892,7 +1897,7 @@
|
|||||||
<div class="world_popup_logo_block">
|
<div class="world_popup_logo_block">
|
||||||
<h3>
|
<h3>
|
||||||
World Info Editor
|
World Info Editor
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#world-info-entry" class="notes-link" target="_blank"><span class="note-link-span">?</span></a>
|
<a href="https://docs.sillytavern.app/usage/core-concepts/worldinfo/#world-info-entry" class="notes-link" target="_blank"><span class="note-link-span">?</span></a>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div id="OpenAllWIEntries" class="menu_button fa-solid fa-expand"></div>
|
<div id="OpenAllWIEntries" class="menu_button fa-solid fa-expand"></div>
|
||||||
@ -1917,7 +1922,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="softprompt_block">
|
<div id="softprompt_block">
|
||||||
<h4>Soft Prompt</h4>
|
<h4>Soft Prompt</h4>
|
||||||
<h5>About soft prompts <a href="https://docs.sillytavern.app/usage/guidebook/#soft-prompts" class="notes-link" target="_blank"><span class="note-link-span">?</span></a></h5>
|
<h5>About soft prompts <a href="https://docs.sillytavern.app/usage/api-connections/koboldai/#soft-prompts" class="notes-link" target="_blank"><span class="note-link-span">?</span></a></h5>
|
||||||
<select id="softprompt">
|
<select id="softprompt">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
</select>
|
</select>
|
||||||
@ -1977,7 +1982,7 @@
|
|||||||
<audio id="audio_message_sound" src="sounds/message.mp3" hidden></audio>
|
<audio id="audio_message_sound" src="sounds/message.mp3" hidden></audio>
|
||||||
<span>
|
<span>
|
||||||
<span data-i18n="Message Sound">Message Sound</span>
|
<span data-i18n="Message Sound">Message Sound</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#message-sound" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/uicustomization/#message-sound" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
@ -2154,7 +2159,7 @@
|
|||||||
<label for="render_formulas">
|
<label for="render_formulas">
|
||||||
<input id="render_formulas" type="checkbox" />
|
<input id="render_formulas" type="checkbox" />
|
||||||
<span data-i18n="Render Formulas">Render Formulas</span>
|
<span data-i18n="Render Formulas">Render Formulas</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#formulas-rendering" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/uicustomization/#formulas-rendering" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</label>
|
</label>
|
||||||
@ -2210,7 +2215,7 @@
|
|||||||
<input id="your_name" name="your_name" placeholder="Enter your name" class="text_pole wide100p" maxlength="50" value="" autocomplete="off">
|
<input id="your_name" name="your_name" placeholder="Enter your name" class="text_pole wide100p" maxlength="50" value="" autocomplete="off">
|
||||||
<div id="your_name_button" class="menu_button fa-solid fa-check" title="Click to set a new User Name">
|
<div id="your_name_button" class="menu_button fa-solid fa-check" title="Click to set a new User Name">
|
||||||
</div>
|
</div>
|
||||||
<div id="lock_user_name" class="menu_button fa-solid fa-user-lock" title="Click to bind your selected persona to the current chat. Click again to remove the binding.">
|
<div id="lock_user_name" class="menu_button fa-solid fa-lock" title="Click to lock your selected persona to the current chat. Click again to remove the lock.">
|
||||||
</div>
|
</div>
|
||||||
<div id="sync_name_button" class="menu_button fa-solid fa-sync" title="Click to set user name for all messages">
|
<div id="sync_name_button" class="menu_button fa-solid fa-sync" title="Click to set user name for all messages">
|
||||||
</div>
|
</div>
|
||||||
@ -2256,17 +2261,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="rm_extensions_block" class="drawer-content closedDrawer">
|
<div id="rm_extensions_block" class="drawer-content closedDrawer">
|
||||||
<div class="extensions_block flex-container">
|
<div class="extensions_block flex-container">
|
||||||
<div class="alignitemscenter flex-container justify wide100p" style="justify-content: space-between;">
|
<div class="alignitemscenter flex-container justifyCenter wide100p" style="justify-content: space-between;">
|
||||||
<h3 class="margin0 flex1">Extensions API:
|
<h3 class="margin0">Extensions API:
|
||||||
<a target="_blank" href="https://github.com/SillyTavern/SillyTavern-extras">
|
<a target="_blank" href="https://github.com/SillyTavern/SillyTavern-extras">
|
||||||
SillyTavern-extras
|
SillyTavern-extras
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
<div id="extensions_status">Not Connected</div>
|
<div class="flex-container">
|
||||||
<label for="extensions_autoconnect">
|
<div id="extensions_status">Not Connected</div>
|
||||||
<input id="extensions_autoconnect" type="checkbox">
|
<label for="extensions_autoconnect">
|
||||||
Auto-connect
|
<input id="extensions_autoconnect" type="checkbox">
|
||||||
</label>
|
Auto-connect
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="alignitemsflexstart flex-container wide100p">
|
<div class="alignitemsflexstart flex-container wide100p">
|
||||||
<input id="extensions_url" type="text" class="flex1 heightFitContent text_pole widthNatural" maxlength="250" placeholder="Extensions URL">
|
<input id="extensions_url" type="text" class="flex1 heightFitContent text_pole widthNatural" maxlength="250" placeholder="Extensions URL">
|
||||||
@ -2293,26 +2300,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav id="right-nav-panel" class="drawer-content closedDrawer fillRight gap5px">
|
<nav id="right-nav-panel" class="drawer-content closedDrawer fillRight gap5px">
|
||||||
<div id="right-nav-panelheader" class="fa-solid fa-grip drag-grabber"></div>
|
<div id="right-nav-panelheader" class="fa-solid fa-grip drag-grabber">
|
||||||
|
|
||||||
<div id="rm_PinAndTabs">
|
</div>
|
||||||
<div id="rm_button_panel_pin_div" title="Locked = Character Management panel will stay open">
|
<div id="CharListButtonAndHotSwaps" class="flex-container flexnowrap">
|
||||||
<input type="checkbox" id="rm_button_panel_pin">
|
<div class="flexFlowColumn flex-container">
|
||||||
<label for="rm_button_panel_pin">
|
<div id="rm_button_panel_pin_div" class="alignitemsflexstart" title="Locked = Character Management panel will stay open">
|
||||||
<div class="fa-solid unchecked fa-lock-open" alt=""></div>
|
<input type="checkbox" id="rm_button_panel_pin">
|
||||||
<div class="fa-solid checked fa-lock" alt=""></div>
|
<label for="rm_button_panel_pin">
|
||||||
</label>
|
<div class="fa-solid unchecked fa-unlock" alt=""></div>
|
||||||
</div>
|
<div class="fa-solid checked fa-lock" alt=""></div>
|
||||||
<div id="right-nav-panel-tabs">
|
</label>
|
||||||
|
</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 fa-solid fa-list-ul" id="rm_button_characters" title="Select/Create Characters"></div>
|
||||||
|
</div>
|
||||||
|
<div name="HotSwapWrapper" class="alignitemscenter flex-container margin0auto">
|
||||||
|
<div class="hotswap flex-container flex1"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<!-- this div structure must be preserved until group peeking can adjust -->
|
||||||
|
<div id="rm_PinAndTabs">
|
||||||
|
<div id="right-nav-panel-tabs" class="">
|
||||||
<div id="rm_button_selected_ch">
|
<div id="rm_button_selected_ch">
|
||||||
<h2></h2>
|
<h2></h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- end group peeking cope structure-->
|
||||||
|
|
||||||
|
|
||||||
<div class="hotswap flex-container justifyCenter">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div name="Solo Char Create/Edit Panel" id="rm_ch_create_block" class="right_menu flex-container flexFlowColumn" style="display: none;">
|
<div name="Solo Char Create/Edit Panel" 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">
|
||||||
@ -2322,28 +2341,31 @@
|
|||||||
<input id="character_name_pole" name="ch_name" class="text_pole" placeholder="Name this character" maxlength="50" value="" autocomplete="off">
|
<input id="character_name_pole" name="ch_name" class="text_pole" placeholder="Name this character" maxlength="50" value="" autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="avatar_div" class="avatar_div">
|
<div id="avatar_div" class="avatar_div alignitemsflexstart justifySpaceBetween">
|
||||||
<div id="avatar_div_div" class="avatar">
|
<div id="avatar_div_div" class="avatar">
|
||||||
<img id="avatar_load_preview" src="img/ai4.png" alt="avatar">
|
<img id="avatar_load_preview" src="img/ai4.png" alt="avatar">
|
||||||
</div>
|
</div>
|
||||||
<div class="form_create_bottom_buttons_block">
|
<div class="flex-container flexFlowColumn">
|
||||||
<label for="add_avatar_button" class="menu_button fa-solid fa-file-image " title="Click to select a new avatar for this character">
|
<div class="form_create_bottom_buttons_block">
|
||||||
<input type="file" id="add_avatar_button" name="avatar" accept="image/png, image/jpeg, image/jpg, image/gif, image/bmp">
|
<label for="add_avatar_button" class="menu_button fa-solid fa-file-image " title="Click to select a new avatar for this character">
|
||||||
</label>
|
<input type="file" id="add_avatar_button" name="avatar" accept="image/png, image/jpeg, image/jpg, image/gif, image/bmp">
|
||||||
<div id="rm_button_back" class="menu_button fa-solid fa-left-long "></div>
|
</label>
|
||||||
<div id="renameCharButton" class="menu_button fa-solid fa-user-pen" title="Rename Character"></div>
|
<div id="rm_button_back" class="menu_button fa-solid fa-left-long "></div>
|
||||||
<div id="favorite_button" class="menu_button fa-solid fa-star" title="Add to Favorites"></div>
|
<div id="renameCharButton" class="menu_button fa-solid fa-user-pen" title="Rename Character"></div>
|
||||||
<input type="hidden" id="fav_checkbox" name="fav" />
|
<div id="favorite_button" class="menu_button fa-solid fa-star" title="Add to Favorites"></div>
|
||||||
<div id="advanced_div" class="menu_button fa-solid fa-book " title="Advanced Definitions"></div>
|
<input type="hidden" id="fav_checkbox" name="fav" />
|
||||||
<div id="export_button" class="menu_button fa-solid fa-file-export " title="Export and Download"></div>
|
<div id="advanced_div" class="menu_button fa-solid fa-book " title="Advanced Definitions"></div>
|
||||||
<div id="dupe_button" class="menu_button fa-solid fa-clone " title="Duplicate Character"></div>
|
<div id="export_button" class="menu_button fa-solid fa-file-export " title="Export and Download"></div>
|
||||||
<label for="create_button" id="create_button_label" class="menu_button fa-solid fa-user-check" title="Create Character">
|
<div id="dupe_button" class="menu_button fa-solid fa-clone " title="Duplicate Character"></div>
|
||||||
<input type="submit" id="create_button" name="create_button">
|
<label for="create_button" id="create_button_label" class="menu_button fa-solid fa-user-check" title="Create Character">
|
||||||
</label>
|
<input type="submit" id="create_button" name="create_button">
|
||||||
<div id="delete_button" class="menu_button fa-solid fa-skull " title="Delete Character"></div>
|
</label>
|
||||||
|
<div id="delete_button" class="menu_button fa-solid fa-skull " title="Delete Character"></div>
|
||||||
|
</div>
|
||||||
|
<div id="result_info" class="justifyCenter flex-container" title="Token counts may be inaccurate and provided just for reference."> </div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div title="Token counts may be inaccurate and provided just for reference." id="result_info"> </div>
|
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
@ -2357,7 +2379,7 @@
|
|||||||
|
|
||||||
<div id="description_div" class="marginBot5">
|
<div id="description_div" class="marginBot5">
|
||||||
<span data-i18n="Description">Description</span>
|
<span data-i18n="Description">Description</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#character-description" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#character-description" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -2367,7 +2389,7 @@
|
|||||||
<div id="first_message_div" class="marginBot5 title_restorable">
|
<div id="first_message_div" class="marginBot5 title_restorable">
|
||||||
<span>
|
<span>
|
||||||
<span data-i18n="First message">First message</span>
|
<span data-i18n="First message">First message</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#first-message" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#first-message" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
@ -2412,7 +2434,7 @@
|
|||||||
<div class="">
|
<div class="">
|
||||||
<div class="flex-container flexnowrap width100p whitespacenowrap">
|
<div class="flex-container flexnowrap width100p whitespacenowrap">
|
||||||
<span data-i18n="Group reply strategy">Group reply strategy</span>
|
<span data-i18n="Group reply strategy">Group reply strategy</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#group-chats" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/groupchats/" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -2597,7 +2619,7 @@
|
|||||||
<div id="personality_div">
|
<div id="personality_div">
|
||||||
<h4>
|
<h4>
|
||||||
<span data-i18n="Personality summary">Personality summary</span>
|
<span data-i18n="Personality summary">Personality summary</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#personality-summary" class="notes-link" target="_blank"><span class="note-link-span">?</span></a>
|
<a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#personality-summary" class="notes-link" target="_blank"><span class="note-link-span">?</span></a>
|
||||||
</h4>
|
</h4>
|
||||||
<textarea id="personality_textarea" name="personality" placeholder="(A brief description of the personality)" form="form_create" class="text_pole" autocomplete="off" rows="1" maxlength="20000"></textarea>
|
<textarea id="personality_textarea" name="personality" placeholder="(A brief description of the personality)" form="form_create" class="text_pole" autocomplete="off" rows="1" maxlength="20000"></textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -2605,7 +2627,7 @@
|
|||||||
<div id="scenario_div">
|
<div id="scenario_div">
|
||||||
<h4>
|
<h4>
|
||||||
<span data-i18n="Scenario">Scenario</span>
|
<span data-i18n="Scenario">Scenario</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#scenario" class="notes-link" target="_blank">
|
<a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#scenario" class="notes-link" target="_blank">
|
||||||
<span class="note-link-span">?</span>
|
<span class="note-link-span">?</span>
|
||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
@ -2627,7 +2649,7 @@
|
|||||||
<div id="mes_example_div" class="flex-container flexFlowColumn">
|
<div id="mes_example_div" class="flex-container flexFlowColumn">
|
||||||
<div>
|
<div>
|
||||||
<h4><span data-i18n="Examples of dialogue">Examples of dialogue</span></h4>
|
<h4><span data-i18n="Examples of dialogue">Examples of dialogue</span></h4>
|
||||||
<h5>Important to set the character's writing style. <a href="https://docs.sillytavern.app/usage/guidebook/#examples-of-dialogue" class="notes-link" target="_blank"><span class="note-link-span">?</span></a></h5>
|
<h5>Important to set the character's writing style. <a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#examples-of-dialogue" class="notes-link" target="_blank"><span class="note-link-span">?</span></a></h5>
|
||||||
</div>
|
</div>
|
||||||
<textarea id="mes_example_textarea" class="flexGrow" name="mes_example" placeholder="(Examples of chat dialog. Begin each example with <start> on a new line.)" form="form_create" maxlength="20000" rows="6"></textarea>
|
<textarea id="mes_example_textarea" class="flexGrow" name="mes_example" placeholder="(Examples of chat dialog. Begin each example with <start> on a new line.)" form="form_create" maxlength="20000" rows="6"></textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -2643,7 +2665,7 @@
|
|||||||
<span id="ChatHistoryCharName"></span>
|
<span id="ChatHistoryCharName"></span>
|
||||||
<br>
|
<br>
|
||||||
<span data-i18n="Chat History">Chat History</span>
|
<span data-i18n="Chat History">Chat History</span>
|
||||||
<a href="https://docs.sillytavern.app/usage/guidebook/#chat-import" class="notes-link" target="_blank"><span class="note-link-span">?</span></a>
|
<a href="https://docs.sillytavern.app/usage/core-concepts/chatfilemanagement/#chat-import" class="notes-link" target="_blank"><span class="note-link-span">?</span></a>
|
||||||
</div>
|
</div>
|
||||||
<form id="form_import_chat" action="javascript:void(null);" method="post" enctype="multipart/form-data" style="display: none;">
|
<form id="form_import_chat" action="javascript:void(null);" method="post" enctype="multipart/form-data" style="display: none;">
|
||||||
<input type="file" id="chat_import_file" accept=".json, .jsonl" name="avatar">
|
<input type="file" id="chat_import_file" accept=".json, .jsonl" name="avatar">
|
||||||
@ -2777,11 +2799,11 @@
|
|||||||
<form class="world_entry_form">
|
<form class="world_entry_form">
|
||||||
<div class="inline-drawer wide100p">
|
<div class="inline-drawer wide100p">
|
||||||
<div class="inline-drawer-toggle inline-drawer-header">
|
<div class="inline-drawer-toggle inline-drawer-header">
|
||||||
<div class="world_entry_thin_controls wide100p">
|
<div class="gap5px world_entry_thin_controls wide100p">
|
||||||
<div class="world_entry_form_control">
|
<div class="world_entry_form_control">
|
||||||
<label for="key">
|
<label for="key">
|
||||||
<h4><span data-i18n="Keywords">Keywords</span></h4>
|
<h4><span data-i18n="Keywords">Keywords</span></h4>
|
||||||
<h5><span data-i18n="Separate with commas">Separate with commas</span></h5>
|
<small><span data-i18n="Separate with commas">Separate with commas</span></small>
|
||||||
</label>
|
</label>
|
||||||
<textarea class="text_pole keyprimarytextpole" name="key" rows="1" placeholder="" maxlength="250"></textarea>
|
<textarea class="text_pole keyprimarytextpole" name="key" rows="1" placeholder="" maxlength="250"></textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -2789,20 +2811,20 @@
|
|||||||
<label for="keysecondary">
|
<label for="keysecondary">
|
||||||
<h4><span data-i18n="Secondary Required Keywords">Secondary Required Keywords</span>
|
<h4><span data-i18n="Secondary Required Keywords">Secondary Required Keywords</span>
|
||||||
</h4>
|
</h4>
|
||||||
<h5><span data-i18n="Separate with commas">Separate with commas</span></h5>
|
<small><span data-i18n="Separate with commas">Separate with commas</span></small>
|
||||||
</label>
|
</label>
|
||||||
<textarea class="text_pole keysecondarytextpole" name="keysecondary" rows="1" placeholder="(secondary keywords here)" maxlength="250"></textarea>
|
<textarea class="text_pole keysecondarytextpole" name="keysecondary" rows="1" placeholder="(secondary keywords here)" maxlength="250"></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>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-drawer-content">
|
<div class="inline-drawer-content flex-container">
|
||||||
<div class="world_entry_thin_controls wide100p">
|
<div class="world_entry_thin_controls wide100p">
|
||||||
<div class="world_entry_form_control">
|
<div class="world_entry_form_control">
|
||||||
<label for="content ">
|
<label for="content ">
|
||||||
<h4><span data-i18n="Content">Content</span></h4>
|
<h4><span data-i18n="Content">Content</span></h4>
|
||||||
<h5><span data-i18n="What this keyword should mean to the AI">What this keyword
|
<small><span data-i18n="What this keyword should mean to the AI">What this keyword
|
||||||
should mean to the AI</span></h5>
|
should mean to the AI</span></small>
|
||||||
</label>
|
</label>
|
||||||
<textarea class="text_pole" name="content" rows="4" placeholder=""></textarea>
|
<textarea class="text_pole" name="content" rows="4" placeholder=""></textarea>
|
||||||
</div>
|
</div>
|
||||||
@ -2812,15 +2834,13 @@
|
|||||||
<div class="world_entry_form_control">
|
<div class="world_entry_form_control">
|
||||||
<label for="comment">
|
<label for="comment">
|
||||||
<h4><span data-i18n="Memo/Note">Memo/Note</span></h4>
|
<h4><span data-i18n="Memo/Note">Memo/Note</span></h4>
|
||||||
<h5><span data-i18n="Not sent to AI">Not sent to AI</span></h5>
|
<small><span data-i18n="Not sent to AI">Not sent to AI</span></small>
|
||||||
</label>
|
</label>
|
||||||
<textarea class="text_pole" rows="1" name="comment" maxlength="250"></textarea>
|
<textarea class="text_pole" rows="1" name="comment" maxlength="250"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex-container flex1 justifySpaceBetween world_entry_form_horizontal">
|
||||||
|
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
|
||||||
<div class="world_entry_form_control world_entry_form_horizontal">
|
|
||||||
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text flex1 ">
|
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" name="constant" />
|
<input type="checkbox" name="constant" />
|
||||||
<span data-i18n="Constant">Constant</span>
|
<span data-i18n="Constant">Constant</span>
|
||||||
@ -2830,7 +2850,7 @@
|
|||||||
<span data-i18n="Selective">Selective</span>
|
<span data-i18n="Selective">Selective</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="world_entry_form_control world_entry_form_radios wi-enter-footer-text flex1">
|
<div class="world_entry_form_control world_entry_form_radios wi-enter-footer-text ">
|
||||||
<div>
|
<div>
|
||||||
<label><input type="radio" name="position" value="0">
|
<label><input type="radio" name="position" value="0">
|
||||||
<span data-i18n="Before Char">Before Char</span>
|
<span data-i18n="Before Char">Before Char</span>
|
||||||
@ -2842,19 +2862,13 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="world_entry_form_control wi-enter-footer-text flex1 flex-container flexNoGap ">
|
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap ">
|
||||||
<!-- world_entry_form_control -->
|
|
||||||
<!-- <label for="order"> -->
|
|
||||||
|
|
||||||
Insertion Order
|
Insertion Order
|
||||||
<!-- Bigger number = inserted earlier -->
|
<input class="text_pole wideMax100px" type="number" name="order" placeholder="" />
|
||||||
|
|
||||||
<!-- </label> -->
|
|
||||||
<input class="text_pole" type="number" name="order" placeholder="" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text flex1">
|
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
|
||||||
<div class="world_entry_form_uid">
|
<div class="world_entry_form_uid">
|
||||||
UID:
|
UID:
|
||||||
|
|
||||||
@ -2866,13 +2880,12 @@
|
|||||||
<span class="world_entry_form_token_counter">0</span>
|
<span class="world_entry_form_token_counter">0</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="wi-enter-footer-text">
|
||||||
<label class="checkbox">
|
<label class="checkbox flex-container alignitemscenter">
|
||||||
<input type="checkbox" name="disable" />
|
<input type="checkbox" name="disable" />
|
||||||
<span data-i18n="Disable">Disable</span>
|
<span data-i18n="Disable">Disable</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<span class="world_popup_expander"> </span>
|
|
||||||
<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>
|
||||||
@ -3138,10 +3151,19 @@
|
|||||||
<div imgfile="" class="avatar">
|
<div imgfile="" class="avatar">
|
||||||
<img src="" alt="User Avatar">
|
<img src="" alt="User Avatar">
|
||||||
</div>
|
</div>
|
||||||
<div class="avatar-buttons">
|
<div class="avatar-buttons avatar-buttons-top">
|
||||||
<button class="menu_button bind_user_name" title="Bind user name to that avatar">
|
<button class="menu_button bind_user_name" title="Bind user name to that avatar">
|
||||||
<i class="fa-solid fa-user-edit"></i>
|
<i class="fa-solid fa-user-edit"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="menu_button set_default_persona" title="Select this as default persona for the new chats.">
|
||||||
|
<i class="fa-solid fa-crown"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="avatar-buttons avatar-buttons-bottom">
|
||||||
|
<button class="menu_button set_user_info" title="Under construction">
|
||||||
|
<i class="fa-solid fa-circle-user"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button class="menu_button delete_avatar" title="Delete persona">
|
<button class="menu_button delete_avatar" title="Delete persona">
|
||||||
<i class="fa-solid fa-trash-alt"></i>
|
<i class="fa-solid fa-trash-alt"></i>
|
||||||
</button>
|
</button>
|
||||||
|
180
public/script.js
180
public/script.js
@ -1464,6 +1464,7 @@ function sendSystemMessage(type, text, extra = {}) {
|
|||||||
|
|
||||||
if (type == system_message_types.HELP) {
|
if (type == system_message_types.HELP) {
|
||||||
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) {
|
||||||
@ -3928,8 +3929,11 @@ function appendUserAvatar(name) {
|
|||||||
const personaName = power_user.personas[name];
|
const personaName = power_user.personas[name];
|
||||||
if (personaName) {
|
if (personaName) {
|
||||||
template.attr('title', personaName);
|
template.attr('title', personaName);
|
||||||
|
} else {
|
||||||
|
template.attr('title', '[Unnamed Persona]');
|
||||||
}
|
}
|
||||||
template.find('.avatar').attr('imgfile', name);
|
template.find('.avatar').attr('imgfile', name);
|
||||||
|
template.toggleClass('default_persona', name === power_user.default_persona)
|
||||||
template.find('img').attr('src', `User Avatars/${name}`);
|
template.find('img').attr('src', `User Avatars/${name}`);
|
||||||
$("#user_avatar_block").append(template);
|
$("#user_avatar_block").append(template);
|
||||||
highlightSelectedAvatar();
|
highlightSelectedAvatar();
|
||||||
@ -3950,9 +3954,9 @@ export function setUserName(value) {
|
|||||||
name1 = value;
|
name1 = value;
|
||||||
if (name1 === undefined || name1 == "")
|
if (name1 === undefined || name1 == "")
|
||||||
name1 = default_user_name;
|
name1 = default_user_name;
|
||||||
console.log(name1);
|
console.log(`User name changed to ${name1}`);
|
||||||
$("#your_name").val(name1);
|
$("#your_name").val(name1);
|
||||||
toastr.success(`Your messages will now be sent as ${name1}`, 'User Name updated');
|
toastr.success(`Your messages will now be sent as ${name1}`, 'Current persona updated');
|
||||||
saveSettings("change_name");
|
saveSettings("change_name");
|
||||||
} else {
|
} else {
|
||||||
toastr.warning('You cannot change your name while sending a message', 'Warning');
|
toastr.warning('You cannot change your name while sending a message', 'Warning');
|
||||||
@ -3962,6 +3966,7 @@ export function setUserName(value) {
|
|||||||
export function autoSelectPersona(name) {
|
export function autoSelectPersona(name) {
|
||||||
for (const [key, value] of Object.entries(power_user.personas)) {
|
for (const [key, value] of Object.entries(power_user.personas)) {
|
||||||
if (value === name) {
|
if (value === name) {
|
||||||
|
console.log(`Auto-selecting persona ${key} for name ${name}`);
|
||||||
$(`.avatar[imgfile="${key}"]`).trigger('click');
|
$(`.avatar[imgfile="${key}"]`).trigger('click');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3978,15 +3983,38 @@ async function bindUserNameToPersona() {
|
|||||||
|
|
||||||
const existingPersona = power_user.personas[avatarId];
|
const existingPersona = power_user.personas[avatarId];
|
||||||
const personaName = await callPopup('<h3>Enter a name for this persona:</h3>(If empty name is provided, this will unbind the name from this avatar)', 'input', existingPersona || '');
|
const personaName = await callPopup('<h3>Enter a name for this persona:</h3>(If empty name is provided, this will unbind the name from this avatar)', 'input', existingPersona || '');
|
||||||
if (personaName) {
|
|
||||||
|
// If the user clicked cancel, don't do anything
|
||||||
|
if (personaName === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (personaName.length > 0) {
|
||||||
|
// If the user clicked ok and entered a name, bind the name to the persona
|
||||||
|
console.log(`Binding persona ${avatarId} to name ${personaName}`);
|
||||||
power_user.personas[avatarId] = personaName;
|
power_user.personas[avatarId] = personaName;
|
||||||
|
|
||||||
|
// If the user is currently using this persona, update the name
|
||||||
|
if (avatarId === user_avatar) {
|
||||||
|
console.log(`Auto-updating user name to ${personaName}`);
|
||||||
|
setUserName(personaName);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// If the user clicked ok, but didn't enter a name, delete the persona
|
||||||
|
console.log(`Unbinding persona ${avatarId}`);
|
||||||
delete power_user.personas[avatarId];
|
delete power_user.personas[avatarId];
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
await getUserAvatars();
|
await getUserAvatars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateUserLockIcon() {
|
||||||
|
const hasLock = !!chat_metadata['persona'];
|
||||||
|
$('#lock_user_name').toggleClass('fa-lock', !hasLock);
|
||||||
|
$('#lock_user_name').toggleClass('fa-unlock', hasLock);
|
||||||
|
}
|
||||||
|
|
||||||
function setUserAvatar() {
|
function setUserAvatar() {
|
||||||
user_avatar = $(this).attr("imgfile");
|
user_avatar = $(this).attr("imgfile");
|
||||||
reloadUserAvatar();
|
reloadUserAvatar();
|
||||||
@ -3997,10 +4025,10 @@ function setUserAvatar() {
|
|||||||
if (personaName && name1 !== personaName) {
|
if (personaName && name1 !== personaName) {
|
||||||
const lockedPersona = chat_metadata['persona'];
|
const lockedPersona = chat_metadata['persona'];
|
||||||
if (lockedPersona && lockedPersona !== user_avatar) {
|
if (lockedPersona && lockedPersona !== user_avatar) {
|
||||||
toastr.warning(
|
toastr.info(
|
||||||
'Click the "Lock" to bind again. Otherwise, the selection will be reset when your reload the chat.',
|
`To permanently set "${personaName}" as the selected persona, unlock and relock it using the "Lock" button. Otherwise, the selection resets upon reloading the chat.`,
|
||||||
`This chat is locked to a different persona (${power_user.personas[lockedPersona]}).`,
|
`This chat is locked to a different persona (${power_user.personas[lockedPersona]}).`,
|
||||||
{ timeOut: 10000, extendedTimeOut: 20000 },
|
{ timeOut: 10000, extendedTimeOut: 20000, preventDuplicates: true },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4008,6 +4036,57 @@ function setUserAvatar() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function setUserInfo() {
|
||||||
|
// TODO Replace with actual implementation
|
||||||
|
callPopup('This functionality is under development.<br>Please check back later.', 'text');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setDefaultPersona() {
|
||||||
|
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
||||||
|
|
||||||
|
if (!avatarId) {
|
||||||
|
console.warn('No avatar id found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentDefault = power_user.default_persona;
|
||||||
|
|
||||||
|
if (power_user.personas[avatarId] === undefined) {
|
||||||
|
console.warn(`No persona name found for avatar ${avatarId}`);
|
||||||
|
toastr.warning('You must bind a name to this persona before you can set it as the default.', 'Persona name not set');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const personaName = power_user.personas[avatarId];
|
||||||
|
|
||||||
|
if (avatarId === currentDefault) {
|
||||||
|
const confirm = await callPopup('Are you sure you want to remove the default persona?', 'confirm');
|
||||||
|
|
||||||
|
if (!confirm) {
|
||||||
|
console.debug('User cancelled removing default persona');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Removing default persona ${avatarId}`);
|
||||||
|
toastr.info('This persona will no longer be used by default when you open a new chat.', `Default persona removed`);
|
||||||
|
delete power_user.default_persona;
|
||||||
|
} else {
|
||||||
|
const confirm = await callPopup(`<h3>Are you sure you want to set "${personaName}" as the default persona?</h3>
|
||||||
|
This name and avatar will be used for all new chats, as well as existing chats where the user persona is not locked.`, 'confirm');
|
||||||
|
|
||||||
|
if (!confirm) {
|
||||||
|
console.debug('User cancelled setting default persona');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
power_user.default_persona = avatarId;
|
||||||
|
toastr.success('This persona will be used by default when you open a new chat.', `Default persona set to ${personaName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSettingsDebounced();
|
||||||
|
await getUserAvatars();
|
||||||
|
}
|
||||||
|
|
||||||
async function deleteUserAvatar() {
|
async function deleteUserAvatar() {
|
||||||
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
||||||
|
|
||||||
@ -4017,6 +4096,7 @@ async function deleteUserAvatar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (avatarId == user_avatar) {
|
if (avatarId == user_avatar) {
|
||||||
|
console.warn(`User tried to delete their current avatar ${avatarId}`);
|
||||||
toastr.warning('You cannot delete the avatar you are currently using', 'Warning');
|
toastr.warning('You cannot delete the avatar you are currently using', 'Warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4024,6 +4104,7 @@ async function deleteUserAvatar() {
|
|||||||
const confirm = await callPopup('Are you sure you want to delete this avatar?', 'confirm');
|
const confirm = await callPopup('Are you sure you want to delete this avatar?', 'confirm');
|
||||||
|
|
||||||
if (!confirm) {
|
if (!confirm) {
|
||||||
|
console.debug('User cancelled deleting avatar');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4036,46 +4117,96 @@ async function deleteUserAvatar() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (request.ok) {
|
if (request.ok) {
|
||||||
|
console.log(`Deleted avatar ${avatarId}`);
|
||||||
delete power_user.personas[avatarId];
|
delete power_user.personas[avatarId];
|
||||||
|
|
||||||
|
if (avatarId === power_user.default_persona) {
|
||||||
|
toastr.warning('The default persona was deleted. You will need to set a new default persona.', 'Default persona deleted');
|
||||||
|
power_user.default_persona = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avatarId === chat_metadata['persona']) {
|
||||||
|
toastr.warning('The locked persona was deleted. You will need to set a new persona for this chat.', 'Persona deleted');
|
||||||
|
delete chat_metadata['persona'];
|
||||||
|
saveMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
await getUserAvatars();
|
await getUserAvatars();
|
||||||
|
updateUserLockIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lockUserNameToChat() {
|
function lockUserNameToChat() {
|
||||||
if (chat_metadata['persona']) {
|
if (chat_metadata['persona']) {
|
||||||
|
console.log(`Unlocking persona for this chat ${chat_metadata['persona']}`);
|
||||||
delete chat_metadata['persona'];
|
delete chat_metadata['persona'];
|
||||||
saveMetadata();
|
saveMetadata();
|
||||||
toastr.info('User persona is now unlocked for this chat. Click the "Lock" to bind again.', 'Persona unlocked');
|
toastr.info('User persona is now unlocked for this chat. Click the "Lock" again to revert.', 'Persona unlocked');
|
||||||
|
updateUserLockIcon();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(user_avatar in power_user.personas)) {
|
if (!(user_avatar in power_user.personas)) {
|
||||||
toastr.info('Creating a new persona for currently selected user name and avatar...', 'Persona not set for this avatar');
|
console.log(`Creating a new persona ${user_avatar}`);
|
||||||
|
toastr.info(
|
||||||
|
'Creating a new persona for currently selected user name and avatar...',
|
||||||
|
'Persona not set for this avatar',
|
||||||
|
{ timeOut: 10000, extendedTimeOut: 20000, },
|
||||||
|
);
|
||||||
power_user.personas[user_avatar] = name1;
|
power_user.personas[user_avatar] = name1;
|
||||||
}
|
}
|
||||||
|
|
||||||
chat_metadata['persona'] = user_avatar;
|
chat_metadata['persona'] = user_avatar;
|
||||||
saveMetadata();
|
saveMetadata();
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
|
console.log(`Locking persona for this chat ${user_avatar}`);
|
||||||
toastr.success(`User persona is locked to ${name1} in this chat`);
|
toastr.success(`User persona is locked to ${name1} in this chat`);
|
||||||
|
updateUserLockIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
eventSource.on(event_types.CHAT_CHANGED, () => {
|
eventSource.on(event_types.CHAT_CHANGED, () => {
|
||||||
// If persona is locked, select it
|
// Define a persona for this chat
|
||||||
|
let chatPersona = '';
|
||||||
|
|
||||||
if (chat_metadata['persona']) {
|
if (chat_metadata['persona']) {
|
||||||
// Find the avatar file
|
// If persona is locked in chat metadata, select it
|
||||||
const personaAvatar = $(`.avatar[imgfile="${chat_metadata['persona']}"]`).trigger('click');
|
console.log(`Using locked persona ${chat_metadata['persona']}`);
|
||||||
|
chatPersona = chat_metadata['persona'];
|
||||||
// Avatar missing (persona deleted)
|
} else if (power_user.default_persona) {
|
||||||
if (personaAvatar.length == 0) {
|
// If default persona is set, select it
|
||||||
console.warn('Persona avatar not found, unlocking persona');
|
console.log(`Using default persona ${power_user.default_persona}`);
|
||||||
delete chat_metadata['persona'];
|
chatPersona = power_user.default_persona;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
personaAvatar.trigger('click');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No persona set: user current settings
|
||||||
|
if (!chatPersona) {
|
||||||
|
console.debug('No default or locked persona set for this chat');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the avatar file
|
||||||
|
const personaAvatar = $(`.avatar[imgfile="${chatPersona}"]`).trigger('click');
|
||||||
|
|
||||||
|
// Avatar missing (persona deleted)
|
||||||
|
if (chat_metadata['persona'] && personaAvatar.length == 0) {
|
||||||
|
console.warn('Persona avatar not found, unlocking persona');
|
||||||
|
delete chat_metadata['persona'];
|
||||||
|
updateUserLockIcon();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default persona missing
|
||||||
|
if (power_user.default_persona && personaAvatar.length == 0) {
|
||||||
|
console.warn('Default persona avatar not found, clearing default persona');
|
||||||
|
power_user.default_persona = null;
|
||||||
|
saveSettingsDebounced();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persona avatar found, select it
|
||||||
|
personaAvatar.trigger('click');
|
||||||
|
updateUserLockIcon();
|
||||||
});
|
});
|
||||||
|
|
||||||
//***************SETTINGS****************//
|
//***************SETTINGS****************//
|
||||||
@ -5024,7 +5155,7 @@ async function deleteMessageImage() {
|
|||||||
mesBlock.find('.mes_img_container').removeClass('img_extra');
|
mesBlock.find('.mes_img_container').removeClass('img_extra');
|
||||||
mesBlock.find('.mes_img').attr('src', '');
|
mesBlock.find('.mes_img').attr('src', '');
|
||||||
saveChatConditional();
|
saveChatConditional();
|
||||||
updateVisibleDivs('#chat', false);
|
/*updateVisibleDivs('#chat', false);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
function enlargeMessageImage() {
|
function enlargeMessageImage() {
|
||||||
@ -5704,9 +5835,10 @@ $(document).ready(function () {
|
|||||||
updateVisibleDivs('#rm_print_characters_block', true);
|
updateVisibleDivs('#rm_print_characters_block', true);
|
||||||
}, 5));
|
}, 5));
|
||||||
|
|
||||||
$("#chat").on('scroll', debounce(() => {
|
// This does not actually increase performance.
|
||||||
|
/*$("#chat").on('scroll', debounce(() => {
|
||||||
updateVisibleDivs('#chat', false);
|
updateVisibleDivs('#chat', false);
|
||||||
}, 10));
|
}, 10));*/
|
||||||
|
|
||||||
let S_TAFocused = false;
|
let S_TAFocused = false;
|
||||||
let S_TAPreviouslyFocused = false;
|
let S_TAPreviouslyFocused = false;
|
||||||
@ -6958,6 +7090,8 @@ $(document).ready(function () {
|
|||||||
|
|
||||||
$(document).on('click', '.bind_user_name', bindUserNameToPersona);
|
$(document).on('click', '.bind_user_name', bindUserNameToPersona);
|
||||||
$(document).on('click', '.delete_avatar', deleteUserAvatar);
|
$(document).on('click', '.delete_avatar', deleteUserAvatar);
|
||||||
|
$(document).on('click', '.set_default_persona', setDefaultPersona);
|
||||||
|
$(document).on('click', '.set_user_info', setUserInfo);
|
||||||
$('#lock_user_name').on('click', lockUserNameToChat);
|
$('#lock_user_name').on('click', lockUserNameToChat);
|
||||||
|
|
||||||
//**************************CHARACTER IMPORT EXPORT*************************//
|
//**************************CHARACTER IMPORT EXPORT*************************//
|
||||||
|
@ -260,16 +260,23 @@ export function RA_CountCharTokens() {
|
|||||||
(power_user.pin_examples ? characters[this_chid].mes_example : ''),
|
(power_user.pin_examples ? characters[this_chid].mes_example : ''),
|
||||||
].join('\n').replace(/\r/gm, '').trim();
|
].join('\n').replace(/\r/gm, '').trim();
|
||||||
perm_tokens = getTokenCount(perm_string);
|
perm_tokens = getTokenCount(perm_string);
|
||||||
} else { console.debug("RA_TC -- no valid char found, closing."); } // if neither, probably safety char or some error in loading
|
// if neither, probably safety char or some error in loading
|
||||||
|
} else { console.debug("RA_TC -- no valid char found, closing."); }
|
||||||
}
|
}
|
||||||
// display the counted tokens
|
// display the counted tokens
|
||||||
if (count_tokens < 1024 && perm_tokens < 1024) {
|
if (count_tokens < 1024 && perm_tokens < 1024) {
|
||||||
$("#result_info").html(count_tokens + " Tokens (" + perm_tokens + " Permanent)"); //display normal if both counts are under 1024
|
//display normal if both counts are under 1024
|
||||||
|
$("#result_info").html(`<small>${count_tokens} Tokens (${perm_tokens} Permanent)</small>`);
|
||||||
} else {
|
} else {
|
||||||
$("#result_info").html(`
|
$("#result_info").html(`
|
||||||
<span class="neutral_warning">${count_tokens}</span> Tokens (<span class="neutral_warning">${perm_tokens}</span><span> Permanent Tokens)
|
<div class="flex-container flexFlowColumn alignitemscenter">
|
||||||
<br>
|
<div class="flex-container flexnowrap flexNoGap">
|
||||||
<div id="chartokenwarning" class="menu_button whitespacenowrap"><a href="https://docs.sillytavern.app/usage/guidebook/#character-tokens" target="_blank">Learn More About Token 'Limits'</a></div>`);
|
<small class="flex-container flexnowrap flexNoGap">
|
||||||
|
<div class="neutral_warning">${count_tokens}</div> Tokens (<div class="neutral_warning">${perm_tokens}</div><div> Permanent)</div>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div id="chartokenwarning" class="menu_button whitespacenowrap"><a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#character-tokens" target="_blank">About Token 'Limits'</a></div>
|
||||||
|
</div>`);
|
||||||
} //warn if either are over 1024
|
} //warn if either are over 1024
|
||||||
}
|
}
|
||||||
//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)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { callPopup, eventSource, event_types, extension_prompt_types, saveSettings, saveSettingsDebounced } from "../script.js";
|
import { callPopup, eventSource, event_types, saveSettings, saveSettingsDebounced } from "../script.js";
|
||||||
import { isSubsetOf, debounce } from "./utils.js";
|
import { isSubsetOf, debounce } from "./utils.js";
|
||||||
export {
|
export {
|
||||||
getContext,
|
getContext,
|
||||||
@ -69,6 +69,20 @@ const getContext = () => window['SillyTavern'].getContext();
|
|||||||
const getApiUrl = () => extension_settings.apiUrl;
|
const getApiUrl = () => extension_settings.apiUrl;
|
||||||
let connectedToApi = false;
|
let connectedToApi = false;
|
||||||
|
|
||||||
|
function showHideExtensionsMenu() {
|
||||||
|
const hasMenuItems = $('#extensionsMenu').children().length > 0;
|
||||||
|
|
||||||
|
// We have menu items, so we can stop checking
|
||||||
|
if (hasMenuItems) {
|
||||||
|
clearInterval(menuInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#extensionsMenuButton').toggle(hasMenuItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Periodically check for new extensions
|
||||||
|
const menuInterval = setInterval(showHideExtensionsMenu, 1000);
|
||||||
|
|
||||||
async function doExtrasFetch(endpoint, args) {
|
async function doExtrasFetch(endpoint, args) {
|
||||||
if (!args) {
|
if (!args) {
|
||||||
args = {}
|
args = {}
|
||||||
@ -219,7 +233,7 @@ function autoConnectInputHandler() {
|
|||||||
|
|
||||||
function addExtensionsButtonAndMenu() {
|
function addExtensionsButtonAndMenu() {
|
||||||
const buttonHTML =
|
const buttonHTML =
|
||||||
`<div id="extensionsMenuButton" class="fa-solid fa-magic-wand-sparkles" title="Extras Extensions" /></div>`;
|
`<div id="extensionsMenuButton" style="display: none;" class="fa-solid fa-magic-wand-sparkles" title="Extras Extensions" /></div>`;
|
||||||
const extensionsMenuHTML = `<div id="extensionsMenu" class="options-content" style="display: none;"></div>`;
|
const extensionsMenuHTML = `<div id="extensionsMenu" class="options-content" style="display: none;"></div>`;
|
||||||
|
|
||||||
$(document.body).append(extensionsMenuHTML);
|
$(document.body).append(extensionsMenuHTML);
|
||||||
|
@ -166,5 +166,5 @@ $(document).ready(function () {
|
|||||||
setInterval(moduleWorker, UPDATE_INTERVAL);
|
setInterval(moduleWorker, UPDATE_INTERVAL);
|
||||||
registerSlashCommand('lock', onLockBackgroundClick, [], " – locks a background for the currently selected chat", true, true);
|
registerSlashCommand('lock', onLockBackgroundClick, [], " – locks a background for the currently selected chat", true, true);
|
||||||
registerSlashCommand('unlock', onUnlockBackgroundClick, [], ' – unlocks a background for the currently selected chat', true, true);
|
registerSlashCommand('unlock', onUnlockBackgroundClick, [], ' – unlocks a background for the currently selected chat', true, true);
|
||||||
registerSlashCommand('autobg', autoBackgroundCommand, ['bgauto'], ' – automatically changes the background based on the chat context', true, true);
|
registerSlashCommand('autobg', autoBackgroundCommand, ['bgauto'], ' – automatically changes the background based on the chat context using the AI request prompt', true, true);
|
||||||
});
|
});
|
||||||
|
@ -59,7 +59,7 @@ function addDiceRollButton() {
|
|||||||
button.hide();
|
button.hide();
|
||||||
|
|
||||||
let popper = Popper.createPopper(button.get(0), dropdown.get(0), {
|
let popper = Popper.createPopper(button.get(0), dropdown.get(0), {
|
||||||
placement: 'bottom',
|
placement: 'top',
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('click touchend', function (e) {
|
$(document).on('click touchend', function (e) {
|
||||||
@ -68,10 +68,10 @@ function addDiceRollButton() {
|
|||||||
if (target.is(button) && !dropdown.is(":visible")) {
|
if (target.is(button) && !dropdown.is(":visible")) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
dropdown.show(200);
|
dropdown.fadeIn(250);
|
||||||
popper.update();
|
popper.update();
|
||||||
} else {
|
} else {
|
||||||
dropdown.hide(200);
|
dropdown.fadeOut(250);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import { chat_metadata, saveSettingsDebounced, this_chid } from "../../../script.js";
|
import {
|
||||||
|
chat_metadata,
|
||||||
|
eventSource,
|
||||||
|
event_types,
|
||||||
|
getTokenCount,
|
||||||
|
saveSettingsDebounced,
|
||||||
|
this_chid,
|
||||||
|
} from "../../../script.js";
|
||||||
import { selected_group } from "../../group-chats.js";
|
import { selected_group } from "../../group-chats.js";
|
||||||
import { ModuleWorkerWrapper, extension_settings, getContext, saveMetadataDebounced } from "../../extensions.js";
|
import { ModuleWorkerWrapper, extension_settings, getContext, saveMetadataDebounced } from "../../extensions.js";
|
||||||
import { registerSlashCommand } from "../../slash-commands.js";
|
import { registerSlashCommand } from "../../slash-commands.js";
|
||||||
@ -66,6 +73,7 @@ function setNotePositionCommand(_, text) {
|
|||||||
|
|
||||||
async function onExtensionFloatingPromptInput() {
|
async function onExtensionFloatingPromptInput() {
|
||||||
chat_metadata[metadata_keys.prompt] = $(this).val();
|
chat_metadata[metadata_keys.prompt] = $(this).val();
|
||||||
|
$('#extension_floating_prompt_token_counter').text(getTokenCount(chat_metadata[metadata_keys.prompt]));
|
||||||
saveMetadataDebounced();
|
saveMetadataDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +101,7 @@ async function onExtensionFloatingPositionInput(e) {
|
|||||||
|
|
||||||
function onExtensionFloatingDefaultInput() {
|
function onExtensionFloatingDefaultInput() {
|
||||||
extension_settings.note.default = $(this).val();
|
extension_settings.note.default = $(this).val();
|
||||||
|
$('#extension_floating_default_token_counter').text(getTokenCount(extension_settings.note.default));
|
||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,6 +182,13 @@ function onANMenuItemClick() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onChatChanged() {
|
||||||
|
const tokenCounter1 = chat_metadata[metadata_keys.prompt] ? getTokenCount(chat_metadata[metadata_keys.prompt]) : 0;
|
||||||
|
const tokenCounter2 = extension_settings.note.default ? getTokenCount(extension_settings.note.default) : 0;
|
||||||
|
$('#extension_floating_prompt_token_counter').text(tokenCounter1);
|
||||||
|
$('#extension_floating_default_token_counter').text(tokenCounter2);
|
||||||
|
}
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
function addExtensionsSettings() {
|
function addExtensionsSettings() {
|
||||||
const settingsHtml = `
|
const settingsHtml = `
|
||||||
@ -195,6 +211,7 @@ function onANMenuItemClick() {
|
|||||||
</small>
|
</small>
|
||||||
|
|
||||||
<textarea id="extension_floating_prompt" class="text_pole" rows="8" maxlength="10000"></textarea>
|
<textarea id="extension_floating_prompt" class="text_pole" rows="8" maxlength="10000"></textarea>
|
||||||
|
<div class="extension_token_counter">Tokens: <span id="extension_floating_prompt_token_counter">0</small></div>
|
||||||
|
|
||||||
<div class="floating_prompt_radio_group">
|
<div class="floating_prompt_radio_group">
|
||||||
<label>
|
<label>
|
||||||
@ -228,6 +245,7 @@ function onANMenuItemClick() {
|
|||||||
|
|
||||||
<textarea id="extension_floating_default" class="text_pole" rows="8" maxlength="10000"
|
<textarea id="extension_floating_default" class="text_pole" rows="8" maxlength="10000"
|
||||||
placeholder="Example:\n[Scenario: wacky adventures; Genre: romantic comedy; Style: verbose, creative]"></textarea>
|
placeholder="Example:\n[Scenario: wacky adventures; Genre: romantic comedy; Style: verbose, creative]"></textarea>
|
||||||
|
<div class="extension_token_counter">Tokens: <span id="extension_floating_default_token_counter">0</small></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -265,4 +283,5 @@ function onANMenuItemClick() {
|
|||||||
registerSlashCommand('depth', setNoteDepthCommand, [], "<span class='monospace'>(number)</span> – sets an author's note depth for in-chat positioning", true, true);
|
registerSlashCommand('depth', setNoteDepthCommand, [], "<span class='monospace'>(number)</span> – sets an author's note depth for in-chat positioning", true, true);
|
||||||
registerSlashCommand('freq', setNoteIntervalCommand, ['interval'], "<span class='monospace'>(number)</span> – sets an author's note insertion frequency", true, true);
|
registerSlashCommand('freq', setNoteIntervalCommand, ['interval'], "<span class='monospace'>(number)</span> – sets an author's note insertion frequency", true, true);
|
||||||
registerSlashCommand('pos', setNotePositionCommand, ['position'], "(<span class='monospace'>chat</span> or <span class='monospace'>scenario</span>) – sets an author's note position", true, true);
|
registerSlashCommand('pos', setNotePositionCommand, ['position'], "(<span class='monospace'>chat</span> or <span class='monospace'>scenario</span>) – sets an author's note position", true, true);
|
||||||
|
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);
|
||||||
})();
|
})();
|
||||||
|
@ -1,61 +1,67 @@
|
|||||||
#floatingPrompt {
|
#floatingPrompt {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
max-width: 90svw;
|
max-width: 90svw;
|
||||||
max-height: 90svh;
|
max-height: 90svh;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 1px solid var(--white30a);
|
border: 1px solid var(--white30a);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
display: none;
|
display: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
box-shadow: 0 0 10px var(--black70a);
|
box-shadow: 0 0 10px var(--black70a);
|
||||||
z-index: 3000;
|
z-index: 3000;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
right: unset;
|
right: unset;
|
||||||
width: calc(((100svw - var(--sheldWidth)) / 2) - 1px);
|
width: calc(((100svw - var(--sheldWidth)) / 2) - 1px);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.floating_prompt_radio_group {
|
.floating_prompt_radio_group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extension_floating_counter {
|
#extension_floating_counter {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: orange;
|
color: orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
.floating_prompt_settings textarea {
|
.extension_token_counter {
|
||||||
font-size: calc(var(--mainFontSize) * 0.9);
|
font-size: calc(var(--mainFontSize) * 0.9);
|
||||||
line-height: 1.2;
|
width: 100%;
|
||||||
}
|
text-align: right;
|
||||||
|
}
|
||||||
#ANClose {
|
|
||||||
height: 15px;
|
.floating_prompt_settings textarea {
|
||||||
aspect-ratio: 1 / 1;
|
font-size: calc(var(--mainFontSize) * 0.9);
|
||||||
font-size: 20px;
|
line-height: 1.2;
|
||||||
opacity: 0.5;
|
}
|
||||||
transition: all 250ms;
|
|
||||||
}
|
#ANClose {
|
||||||
|
height: 15px;
|
||||||
#ANClose:hover {
|
aspect-ratio: 1 / 1;
|
||||||
cursor: pointer;
|
font-size: 20px;
|
||||||
opacity: 1;
|
opacity: 0.5;
|
||||||
}
|
transition: all 250ms;
|
||||||
|
}
|
||||||
.panelControlBar {
|
|
||||||
position: absolute;
|
#ANClose:hover {
|
||||||
right: 5px;
|
cursor: pointer;
|
||||||
top: 5px;
|
opacity: 1;
|
||||||
margin-right: 5px;
|
}
|
||||||
}
|
|
||||||
|
.panelControlBar {
|
||||||
#floatingPrompt .drag-grabber {
|
position: absolute;
|
||||||
position: unset;
|
right: 5px;
|
||||||
}
|
top: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#floatingPrompt .drag-grabber {
|
||||||
|
position: unset;
|
||||||
|
}
|
||||||
|
@ -547,7 +547,7 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if not swipe - check if message generated already
|
// if not swipe - check if message generated already
|
||||||
if (type !== "swipe" && !isMultigenEnabled() && chat.length == messagesBefore) {
|
if (generateType === "group_chat" && !isMultigenEnabled() && chat.length == messagesBefore) {
|
||||||
await delay(100);
|
await delay(100);
|
||||||
}
|
}
|
||||||
// if swipe - see if message changed
|
// if swipe - see if message changed
|
||||||
@ -1418,6 +1418,14 @@ function onGroupScenarioRemoveClick() {
|
|||||||
$(this).closest('.group_scenario').find('.group_chat_scenario').val('').trigger('input');
|
$(this).closest('.group_scenario').find('.group_chat_scenario').val('').trigger('input');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onSendTextareaInput() {
|
||||||
|
if (is_group_automode_enabled) {
|
||||||
|
// Wait for current automode generation to finish
|
||||||
|
is_group_automode_enabled = false;
|
||||||
|
$("#rm_group_automode").prop("checked", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function stopAutoModeGeneration() {
|
function stopAutoModeGeneration() {
|
||||||
if (groupAutoModeAbortController) {
|
if (groupAutoModeAbortController) {
|
||||||
groupAutoModeAbortController.abort();
|
groupAutoModeAbortController.abort();
|
||||||
@ -1440,4 +1448,5 @@ jQuery(() => {
|
|||||||
is_group_automode_enabled = value;
|
is_group_automode_enabled = value;
|
||||||
eventSource.once(event_types.GENERATION_STOPPED, stopAutoModeGeneration);
|
eventSource.once(event_types.GENERATION_STOPPED, stopAutoModeGeneration);
|
||||||
});
|
});
|
||||||
|
$("#send_textarea").on("keyup", onSendTextareaInput);
|
||||||
});
|
});
|
||||||
|
@ -44,7 +44,7 @@ If you have any objections to these requirements, please mention them specifical
|
|||||||
|
|
||||||
If you accept the requirements, please confirm this by replying with "${DEFAULT_JAILBREAK_RESPONSE}", and nothing more. Upon receiving your accurate confirmation message, I will specify the context of the scene and {{char}}'s characteristics, background, and personality in the next message.`;
|
If you accept the requirements, please confirm this by replying with "${DEFAULT_JAILBREAK_RESPONSE}", and nothing more. Upon receiving your accurate confirmation message, I will specify the context of the scene and {{char}}'s characteristics, background, and personality in the next message.`;
|
||||||
|
|
||||||
const DEFAULT_CHARACTER_NUDGE_MESSAGE = "[Unless otherwise stated by {{user}}, your the next response shall only be written from the point of view of {{char}}. Do not seek approval of your writing style at the end of the response.]";
|
const DEFAULT_CHARACTER_NUDGE_MESSAGE = "[Unless otherwise stated by {{user}}, your the next response shall only be written from the point of view of {{char}}. Do not seek approval of your writing style at the end of the response. Don't reply with <ACK>.]";
|
||||||
const DEFAULT_IMPERSONATION_PROMPT = "[Write 1 reply only in internet RP style from the point of view of {{user}}, using the chat history so far as a guideline for the writing style of {{user}}. Don't write as {{char}} or system.]";
|
const DEFAULT_IMPERSONATION_PROMPT = "[Write 1 reply only in internet RP style from the point of view of {{user}}, using the chat history so far as a guideline for the writing style of {{user}}. Don't write as {{char}} or system.]";
|
||||||
|
|
||||||
const poe_settings = {
|
const poe_settings = {
|
||||||
@ -265,7 +265,7 @@ async function generatePoe(type, finalPrompt, signal) {
|
|||||||
const isQuiet = type === 'quiet';
|
const isQuiet = type === 'quiet';
|
||||||
let reply = '';
|
let reply = '';
|
||||||
|
|
||||||
if (max_context > POE_TOKEN_LENGTH) {
|
if (max_context > POE_TOKEN_LENGTH && poe_settings.bot !== 'a2_100k') {
|
||||||
console.debug('Prompt is too long, sending in chunks');
|
console.debug('Prompt is too long, sending in chunks');
|
||||||
const result = await sendChunkedMessage(finalPrompt, !isQuiet, signal)
|
const result = await sendChunkedMessage(finalPrompt, !isQuiet, signal)
|
||||||
reply = result.reply;
|
reply = result.reply;
|
||||||
|
@ -146,6 +146,7 @@ let power_user = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
personas: {},
|
personas: {},
|
||||||
|
default_persona: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
let themes = [];
|
let themes = [];
|
||||||
|
@ -98,7 +98,7 @@ const getSlashCommandsHelp = parser.getHelpString.bind(parser);
|
|||||||
parser.addCommand('help', helpCommandCallback, ['?'], ' – displays this help message', true, true);
|
parser.addCommand('help', helpCommandCallback, ['?'], ' – displays this help message', true, true);
|
||||||
parser.addCommand('name', setNameCallback, ['persona'], '<span class="monospace">(name)</span> – sets user name and persona avatar (if set)', true, true);
|
parser.addCommand('name', setNameCallback, ['persona'], '<span class="monospace">(name)</span> – sets user name and persona avatar (if set)', true, true);
|
||||||
parser.addCommand('sync', syncCallback, [], ' – syncs user name in user-attributed messages in the current chat', true, true);
|
parser.addCommand('sync', syncCallback, [], ' – syncs user name in user-attributed messages in the current chat', true, true);
|
||||||
parser.addCommand('bind', bindCallback, [], ' – binds/unbinds a persona (name and avatar) to the current chat', true, true);
|
parser.addCommand('lock', bindCallback, ['bind'], ' – locks/unlocks a persona (name and avatar) to the current chat', true, true);
|
||||||
parser.addCommand('bg', setBackgroundCallback, ['background'], '<span class="monospace">(filename)</span> – sets a background according to filename, partial names allowed, will set the first one alphabetically if multiple files begin with the provided argument string', false, true);
|
parser.addCommand('bg', setBackgroundCallback, ['background'], '<span class="monospace">(filename)</span> – sets a background according to filename, partial names allowed, will set the first one alphabetically if multiple files begin with the provided argument string', false, true);
|
||||||
parser.addCommand('sendas', sendMessageAs, [], ` – sends message as a specific character.<br>Example:<br><pre><code>/sendas Chloe\nHello, guys!</code></pre>will send "Hello, guys!" from "Chloe".<br>Uses character avatar if it exists in the characters list.`, true, true);
|
parser.addCommand('sendas', sendMessageAs, [], ` – sends message as a specific character.<br>Example:<br><pre><code>/sendas Chloe\nHello, guys!</code></pre>will send "Hello, guys!" from "Chloe".<br>Uses character avatar if it exists in the characters list.`, true, true);
|
||||||
parser.addCommand('sys', sendNarratorMessage, [], '<span class="monospace">(text)</span> – sends message as a system narrator', false, true);
|
parser.addCommand('sys', sendNarratorMessage, [], '<span class="monospace">(text)</span> – sends message as a system narrator', false, true);
|
||||||
@ -262,6 +262,7 @@ function executeSlashCommands(text) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.debug('Slash command executing:', result);
|
||||||
result.command.callback(result.args, result.value);
|
result.command.callback(result.args, result.value);
|
||||||
|
|
||||||
if (result.command.interruptsGeneration) {
|
if (result.command.interruptsGeneration) {
|
||||||
|
110
public/style.css
110
public/style.css
@ -34,6 +34,7 @@
|
|||||||
--orangered: rgb(255, 90, 0);
|
--orangered: rgb(255, 90, 0);
|
||||||
--greyCAIbg: rgb(36, 36, 37);
|
--greyCAIbg: rgb(36, 36, 37);
|
||||||
--ivory: rgb(220, 220, 210);
|
--ivory: rgb(220, 220, 210);
|
||||||
|
--golden: rgba(212, 175, 55, 1);
|
||||||
|
|
||||||
|
|
||||||
/*Default Theme, will be changed by ToolCool Color Picker*/
|
/*Default Theme, will be changed by ToolCool Color Picker*/
|
||||||
@ -296,6 +297,7 @@ hr {
|
|||||||
background-image: linear-gradient(90deg, var(--transparent), var(--white30a), var(--transparent));
|
background-image: linear-gradient(90deg, var(--transparent), var(--white30a), var(--transparent));
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
|
min-height: 1px;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,6 +897,10 @@ select {
|
|||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin5 {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
#description_textarea,
|
#description_textarea,
|
||||||
#firstmessage_textarea {
|
#firstmessage_textarea {
|
||||||
height: -webkit-fill-available;
|
height: -webkit-fill-available;
|
||||||
@ -993,10 +999,17 @@ input[type="file"] {
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#right-nav-panel-tabs .right_menu_button {
|
#right-nav-panel-tabs .right_menu_button,
|
||||||
|
#CharListButtonAndHotSwaps .right_menu_button {
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#chartokenwarning.menu_button {
|
||||||
|
font-size: unset;
|
||||||
|
height: fit-content;
|
||||||
|
aspect-ratio: unset;
|
||||||
|
}
|
||||||
|
|
||||||
/* ##################################################################### */
|
/* ##################################################################### */
|
||||||
/* Right Panel's Upper Tabs */
|
/* Right Panel's Upper Tabs */
|
||||||
/* ##################################################################### */
|
/* ##################################################################### */
|
||||||
@ -1239,7 +1252,8 @@ select option:not(:checked) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#form_character_search_form .menu_button,
|
#form_character_search_form .menu_button,
|
||||||
#GroupFavDelOkBack .menu_button {
|
#GroupFavDelOkBack .menu_button,
|
||||||
|
.avatar-container .menu_button {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@ -1326,6 +1340,10 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
width: calc(100% - 70px);
|
width: calc(100% - 70px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wideMax100px {
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
.widthUnset {
|
.widthUnset {
|
||||||
width: unset;
|
width: unset;
|
||||||
}
|
}
|
||||||
@ -1432,7 +1450,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
margin-bottom: 6px;
|
/* margin-bottom: 6px; */
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1446,7 +1464,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 0 0 100%;
|
flex: 0 0 100%;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin-bottom: 4px;
|
/* margin-bottom: 4px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1529,21 +1547,35 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.avatar-buttons-bottom {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-buttons-top {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ross should be able to handle this later */
|
||||||
|
/*.big-avatars .avatar-buttons{
|
||||||
|
justify-content: center;
|
||||||
|
width: fit-content;
|
||||||
|
}*/
|
||||||
|
|
||||||
.avatar-buttons {
|
.avatar-buttons {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar_div .avatar {
|
.avatar_div .avatar {
|
||||||
margin-left: 4px;
|
/* margin-left: 4px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
width: 70px;
|
width: 70px; */
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -1612,7 +1644,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#result_info {
|
#result_info {
|
||||||
font-size: calc(var(--mainFontSize) - 0.2rem);
|
font-size: calc(var(--mainFontSize) - 0.1rem);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1885,27 +1917,6 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#world_popup_bottom_holder div:not(:first-of-type) {
|
|
||||||
margin-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#world_info_buttons {
|
|
||||||
margin-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.world_entry {
|
|
||||||
padding: 0 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.world_entry:not(:last-child)::after {
|
|
||||||
margin-top: 1rem;
|
|
||||||
height: 1px;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
content: '';
|
|
||||||
background-image: linear-gradient(270deg, rgba(0, 0, 0, 0), rgba(100, 100, 100, 0.75), rgba(0, 0, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
.world_popup_logo_block {
|
.world_popup_logo_block {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -1980,7 +1991,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
.world_entry_form_control {
|
.world_entry_form_control {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin: 0 10px;
|
/* margin: 0 10px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.world_entry_thin_controls {
|
.world_entry_thin_controls {
|
||||||
@ -1998,7 +2009,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
|
|
||||||
.world_entry_form_control label h4 {
|
.world_entry_form_control label h4 {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
margin-top: 0.5rem;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.world_entry_form_control label h5 {
|
.world_entry_form_control label h5 {
|
||||||
@ -2010,12 +2021,13 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
height: auto;
|
height: auto;
|
||||||
/* width: auto; */
|
/* width: auto; */
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.world_entry_form_control.world_entry_form_horizontal {
|
.world_entry_form_control.world_entry_form_horizontal {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 5px;
|
/* margin-top: 5px; */
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2077,6 +2089,11 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
|||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Override toastr default styles */
|
||||||
|
body #toast-container>div {
|
||||||
|
opacity: 0.95;
|
||||||
|
}
|
||||||
|
|
||||||
#dialogue_del_mes {
|
#dialogue_del_mes {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -2152,6 +2169,15 @@ input[type='checkbox']:not(#nav-toggle):not(#rm_button_panel_pin):not(#lm_button
|
|||||||
outline: 2px solid transparent;
|
outline: 2px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#user_avatar_block .default_persona .avatar {
|
||||||
|
border: 2px solid var(--golden);
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#user_avatar_block .default_persona .set_default_persona {
|
||||||
|
color: var(--golden);
|
||||||
|
}
|
||||||
|
|
||||||
#user_avatar_block .avatar img {
|
#user_avatar_block .avatar img {
|
||||||
width: 64px;
|
width: 64px;
|
||||||
height: 64px;
|
height: 64px;
|
||||||
@ -2253,8 +2279,8 @@ input[type="range"]::-webkit-slider-thumb {
|
|||||||
/*Notes '?' links*/
|
/*Notes '?' links*/
|
||||||
|
|
||||||
.note-link-span {
|
.note-link-span {
|
||||||
color: var(--sienna);
|
color: var(--SmartThemeQuoteColor);
|
||||||
border: 1px solid var(--sienna);
|
border: 1px solid var(--SmartThemeQuoteColor);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
line-height: var(--mainFontSize);
|
line-height: var(--mainFontSize);
|
||||||
font-size: var(--mainFontSize);
|
font-size: var(--mainFontSize);
|
||||||
@ -3852,6 +3878,10 @@ toolcool-color-picker {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin0auto {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.margin-r5 {
|
.margin-r5 {
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
@ -4321,7 +4351,7 @@ body.waifuMode #avatar_zoom_popup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.world_entry_form_control.world_entry_form_horizontal {
|
.world_entry_form_control.world_entry_form_horizontal {
|
||||||
flex-direction: column;
|
/* flex-direction: column; */
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
row-gap: 0.5rem;
|
row-gap: 0.5rem;
|
||||||
}
|
}
|
||||||
@ -4462,9 +4492,9 @@ body.waifuMode #avatar_zoom_popup {
|
|||||||
font-size: calc(var(--mainFontSize) - .1rem);
|
font-size: calc(var(--mainFontSize) - .1rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar_div {
|
/* .avatar_div {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
} */
|
||||||
|
|
||||||
#character_popup {
|
#character_popup {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -4482,7 +4512,7 @@ body.waifuMode #avatar_zoom_popup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.drawer25pWidth {
|
.drawer25pWidth {
|
||||||
flex-basis: max(calc(100% / 4 - 10px), 200px);
|
flex-basis: max(calc(100% / 4 - 10px), 190px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.expression-holder {
|
.expression-holder {
|
||||||
@ -4550,7 +4580,7 @@ body.waifuMode #avatar_zoom_popup {
|
|||||||
|
|
||||||
@media screen and (max-width: 450px) {
|
@media screen and (max-width: 450px) {
|
||||||
.drawer25pWidth {
|
.drawer25pWidth {
|
||||||
flex-basis: max(calc(100% / 2 - 10px), 200px);
|
flex-basis: max(calc(100% / 2 - 10px), 180px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
33
server.js
33
server.js
@ -385,9 +385,8 @@ app.post("/generate", jsonParser, async function (request, response_generate = r
|
|||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAX_RETRIES = 10;
|
const MAX_RETRIES = 50;
|
||||||
const delayAmount = 3000;
|
const delayAmount = 2500;
|
||||||
|
|
||||||
let fetch, url, response;
|
let fetch, url, response;
|
||||||
for (let i = 0; i < MAX_RETRIES; i++) {
|
for (let i = 0; i < MAX_RETRIES; i++) {
|
||||||
try {
|
try {
|
||||||
@ -420,15 +419,23 @@ app.post("/generate", jsonParser, async function (request, response_generate = r
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// response
|
// response
|
||||||
switch (error.statusCode) {
|
switch (error?.status) {
|
||||||
|
case 403:
|
||||||
case 503: // retry in case of temporary service issue, possibly caused by a queue failure?
|
case 503: // retry in case of temporary service issue, possibly caused by a queue failure?
|
||||||
|
console.debug(`KoboldAI is busy. Retry attempt ${i+1} of ${MAX_RETRIES}...`);
|
||||||
await delay(delayAmount);
|
await delay(delayAmount);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if ('status' in error) {
|
||||||
|
console.log('Status Code from Kobold:', error.status);
|
||||||
|
}
|
||||||
return response_generate.send({ error: true });
|
return response_generate.send({ error: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('Max retries exceeded. Giving up.');
|
||||||
|
return response_generate.send({ error: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
//************** Text generation web UI
|
//************** Text generation web UI
|
||||||
@ -685,11 +692,11 @@ function getVersion() {
|
|||||||
pkgVersion = pkgJson.version;
|
pkgVersion = pkgJson.version;
|
||||||
if (!process.pkg && commandExistsSync('git')) {
|
if (!process.pkg && commandExistsSync('git')) {
|
||||||
gitRevision = require('child_process')
|
gitRevision = require('child_process')
|
||||||
.execSync('git rev-parse --short HEAD', { cwd: process.cwd() })
|
.execSync('git rev-parse --short HEAD', { cwd: process.cwd(), stdio: ['ignore', 'pipe', 'ignore'] })
|
||||||
.toString().trim();
|
.toString().trim();
|
||||||
|
|
||||||
gitBranch = require('child_process')
|
gitBranch = require('child_process')
|
||||||
.execSync('git rev-parse --abbrev-ref HEAD', { cwd: process.cwd() })
|
.execSync('git rev-parse --abbrev-ref HEAD', { cwd: process.cwd(), stdio: ['ignore', 'pipe', 'ignore'] })
|
||||||
.toString().trim();
|
.toString().trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2421,7 +2428,7 @@ app.post('/generate_poe', jsonParser, async (request, response) => {
|
|||||||
if (streaming) {
|
if (streaming) {
|
||||||
try {
|
try {
|
||||||
let reply = '';
|
let reply = '';
|
||||||
for await (const mes of client.send_message(bot, prompt, false, 30, abortController.signal)) {
|
for await (const mes of client.send_message(bot, prompt, false, 60, abortController.signal)) {
|
||||||
if (response.headersSent === false) {
|
if (response.headersSent === false) {
|
||||||
response.writeHead(200, {
|
response.writeHead(200, {
|
||||||
'Content-Type': 'text/plain;charset=utf-8',
|
'Content-Type': 'text/plain;charset=utf-8',
|
||||||
@ -2454,7 +2461,7 @@ app.post('/generate_poe', jsonParser, async (request, response) => {
|
|||||||
try {
|
try {
|
||||||
let reply;
|
let reply;
|
||||||
let messageId;
|
let messageId;
|
||||||
for await (const mes of client.send_message(bot, prompt, false, 30, abortController.signal)) {
|
for await (const mes of client.send_message(bot, prompt, false, 60, abortController.signal)) {
|
||||||
reply = mes.text;
|
reply = mes.text;
|
||||||
messageId = mes.messageId;
|
messageId = mes.messageId;
|
||||||
}
|
}
|
||||||
@ -3151,7 +3158,7 @@ async function postAsync(url, args) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(response);
|
throw response;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAsync(url, args) {
|
function getAsync(url, args) {
|
||||||
@ -3179,6 +3186,10 @@ const autorunUrl = new URL(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const setupTasks = async function () {
|
const setupTasks = async function () {
|
||||||
|
const version = getVersion();
|
||||||
|
|
||||||
|
console.log(`SillyTavern ${version.pkgVersion}` + (version.gitBranch ? ` '${version.gitBranch}' (${version.gitRevision})` : ''));
|
||||||
|
|
||||||
migrateSecrets();
|
migrateSecrets();
|
||||||
ensurePublicDirectoriesExist();
|
ensurePublicDirectoriesExist();
|
||||||
await ensureThumbnailCache();
|
await ensureThumbnailCache();
|
||||||
@ -3196,6 +3207,10 @@ const setupTasks = async function () {
|
|||||||
|
|
||||||
if (autorun) open(autorunUrl.toString());
|
if (autorun) open(autorunUrl.toString());
|
||||||
console.log('SillyTavern is listening on: ' + tavernUrl);
|
console.log('SillyTavern is listening on: ' + tavernUrl);
|
||||||
|
|
||||||
|
if (listen) {
|
||||||
|
console.log('\n0.0.0.0 means SillyTavern is listening on all network interfaces (Wi-Fi, LAN, localhost). If you want to limit it only to internal localhost (127.0.0.1), change the setting in config.conf to “listen=false”\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen && !config.whitelistMode && !config.basicAuthMode) {
|
if (listen && !config.whitelistMode && !config.basicAuthMode) {
|
||||||
|
@ -608,7 +608,7 @@ class Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async *send_message(chatbot, message, with_chat_break = false, timeout = 30, signal = null) {
|
async *send_message(chatbot, message, with_chat_break = false, timeout = 60, signal = null) {
|
||||||
await this.ws_ping();
|
await this.ws_ping();
|
||||||
|
|
||||||
if (this.auto_reconnect) {
|
if (this.auto_reconnect) {
|
||||||
|
Reference in New Issue
Block a user