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">
|
||||
<input type="checkbox" id="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>
|
||||
</label>
|
||||
</div>
|
||||
@ -116,7 +116,7 @@
|
||||
<div id="respective-presets-block" class="width100p">
|
||||
<div id="kobold_api-presets">
|
||||
<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>
|
||||
</a>
|
||||
</h3>
|
||||
@ -127,7 +127,7 @@
|
||||
<div id="novel_api-presets">
|
||||
<h3>
|
||||
<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>
|
||||
</a>
|
||||
</h3>
|
||||
@ -340,7 +340,7 @@
|
||||
</div>
|
||||
<div class="range-block-range-and-counter">
|
||||
<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 class="range-block-counter">
|
||||
<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.
|
||||
It extends the context window in exchange for reply generation speed.
|
||||
</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 id="poe_send_jailbreak" class="menu_button widthFitContent" title="Attempts to automatically jailbreak the bot">
|
||||
Send Jailbreak
|
||||
@ -1293,12 +1299,12 @@
|
||||
</label>
|
||||
|
||||
<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.
|
||||
</h5>
|
||||
<div>
|
||||
</small>
|
||||
<!-- <div>
|
||||
<a id="horde_kudos" href="javascript:void(0);">View my Kudos</a>
|
||||
</div>
|
||||
</div> -->
|
||||
<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">
|
||||
<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>
|
||||
</h4>
|
||||
<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>
|
||||
<option>-- Horde models not loaded --</option>
|
||||
</select>
|
||||
@ -1327,7 +1333,7 @@
|
||||
<form action="javascript:void(null);" method="post" enctype="multipart/form-data">
|
||||
<div id="kobold_api_block">
|
||||
<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_button" class="menu_button" type="submit" value="Connect">
|
||||
<div id="api_loading" class="api-load-icon fa-solid fa-hourglass fa-spin"></div>
|
||||
@ -1345,9 +1351,7 @@
|
||||
<span>
|
||||
<ol>
|
||||
<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
|
||||
directions</span> </a> <span data-i18n="to get your NovelAI API key.">to
|
||||
get your NovelAI API key.</span>
|
||||
<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>
|
||||
</li>
|
||||
<li><span data-i18n="Enter it in the box below">Enter it in the box below:</span>
|
||||
</li>
|
||||
@ -1363,7 +1367,7 @@
|
||||
<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>
|
||||
<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>
|
||||
</a>
|
||||
</h4>
|
||||
@ -1379,7 +1383,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<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">
|
||||
oobabooga/text-generation-webui
|
||||
</a>
|
||||
@ -1388,15 +1392,15 @@
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex-container">
|
||||
<div class="flex-container flexFlowColumn">
|
||||
<div class="flex1">
|
||||
<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">
|
||||
</div>
|
||||
<div class="flex1">
|
||||
<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">
|
||||
</div>
|
||||
</div>
|
||||
@ -1422,7 +1426,7 @@
|
||||
<span>
|
||||
<ol>
|
||||
<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.
|
||||
</li>
|
||||
<li>Enter it in the box below:</li>
|
||||
@ -1521,7 +1525,7 @@
|
||||
<span>
|
||||
<ol>
|
||||
<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>Enter it in the box below:</li>
|
||||
</ol>
|
||||
@ -1570,7 +1574,7 @@
|
||||
</div>
|
||||
<div class="drawer-content">
|
||||
<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>
|
||||
</a>
|
||||
</h3>
|
||||
@ -1616,7 +1620,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<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>
|
||||
</a>
|
||||
</h4>
|
||||
@ -1693,7 +1697,7 @@
|
||||
<h4><span data-i18n="Context Formatting">Context Formatting</span></h4>
|
||||
<div>
|
||||
<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>
|
||||
</a>
|
||||
</h4>
|
||||
@ -1709,7 +1713,7 @@
|
||||
<div class="range-block">
|
||||
<div class="range-block-title justifyLeft">
|
||||
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>
|
||||
</a>
|
||||
</div>
|
||||
@ -1772,7 +1776,7 @@
|
||||
<div>
|
||||
<h4>
|
||||
<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>
|
||||
</a>
|
||||
</h4>
|
||||
@ -1807,14 +1811,14 @@
|
||||
<div id="WI_panel_pin_div" title="Locked = World Editor will stay open">
|
||||
<input type="checkbox" id="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>
|
||||
</label>
|
||||
</div>
|
||||
<div id="wi-holder">
|
||||
<div id="wi-holder" class="margin5">
|
||||
<h3>
|
||||
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>
|
||||
</a>
|
||||
</h3>
|
||||
@ -1832,6 +1836,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex-container alignitemscenter">
|
||||
<div name="WIScanAndTokens" class="flex1 flex-container flexFlowColumn">
|
||||
<div class="flex1 range-block">
|
||||
<div class="range-block-title">
|
||||
<span data-i18n="Scan Depth">Scan Depth</span>
|
||||
@ -1863,8 +1868,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex1 range-block flex-container">
|
||||
</div>
|
||||
<div class="range-block flex-container flexFlowColumn">
|
||||
<label title="Entries can activate other entries by mentioning their keywords" class="checkbox_label">
|
||||
<input id="world_info_recursive" type="checkbox" />
|
||||
<span>
|
||||
@ -1892,7 +1897,7 @@
|
||||
<div class="world_popup_logo_block">
|
||||
<h3>
|
||||
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>
|
||||
</div>
|
||||
<div id="OpenAllWIEntries" class="menu_button fa-solid fa-expand"></div>
|
||||
@ -1917,7 +1922,7 @@
|
||||
</div>
|
||||
<div id="softprompt_block">
|
||||
<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">
|
||||
<option value="">None</option>
|
||||
</select>
|
||||
@ -1977,7 +1982,7 @@
|
||||
<audio id="audio_message_sound" src="sounds/message.mp3" hidden></audio>
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
@ -2154,7 +2159,7 @@
|
||||
<label for="render_formulas">
|
||||
<input id="render_formulas" type="checkbox" />
|
||||
<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>
|
||||
</a>
|
||||
</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">
|
||||
<div id="your_name_button" class="menu_button fa-solid fa-check" title="Click to set a new User Name">
|
||||
</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 id="sync_name_button" class="menu_button fa-solid fa-sync" title="Click to set user name for all messages">
|
||||
</div>
|
||||
@ -2256,18 +2261,20 @@
|
||||
</div>
|
||||
<div id="rm_extensions_block" class="drawer-content closedDrawer">
|
||||
<div class="extensions_block flex-container">
|
||||
<div class="alignitemscenter flex-container justify wide100p" style="justify-content: space-between;">
|
||||
<h3 class="margin0 flex1">Extensions API:
|
||||
<div class="alignitemscenter flex-container justifyCenter wide100p" style="justify-content: space-between;">
|
||||
<h3 class="margin0">Extensions API:
|
||||
<a target="_blank" href="https://github.com/SillyTavern/SillyTavern-extras">
|
||||
SillyTavern-extras
|
||||
</a>
|
||||
</h3>
|
||||
<div class="flex-container">
|
||||
<div id="extensions_status">Not Connected</div>
|
||||
<label for="extensions_autoconnect">
|
||||
<input id="extensions_autoconnect" type="checkbox">
|
||||
Auto-connect
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<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_api_key" type="text" class="flex1 heightFitContent text_pole widthNatural" maxlength="250" placeholder="API key">
|
||||
@ -2293,26 +2300,38 @@
|
||||
</div>
|
||||
</div>
|
||||
<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 id="rm_button_panel_pin_div" title="Locked = Character Management panel will stay open">
|
||||
</div>
|
||||
<div id="CharListButtonAndHotSwaps" class="flex-container flexnowrap">
|
||||
<div class="flexFlowColumn flex-container">
|
||||
<div id="rm_button_panel_pin_div" class="alignitemsflexstart" title="Locked = Character Management panel will stay open">
|
||||
<input type="checkbox" id="rm_button_panel_pin">
|
||||
<label for="rm_button_panel_pin">
|
||||
<div class="fa-solid unchecked fa-lock-open" alt=""></div>
|
||||
<div class="fa-solid unchecked fa-unlock" alt=""></div>
|
||||
<div class="fa-solid checked fa-lock" alt=""></div>
|
||||
</label>
|
||||
</div>
|
||||
<div id="right-nav-panel-tabs">
|
||||
<div class="right_menu_button fa-solid fa-list-ul" id="rm_button_characters" title="Select/Create Characters"></div>
|
||||
</div>
|
||||
<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">
|
||||
<h2></h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hotswap flex-container justifyCenter">
|
||||
</div>
|
||||
</div>
|
||||
<!-- end group peeking cope structure-->
|
||||
|
||||
|
||||
|
||||
<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">
|
||||
@ -2322,10 +2341,11 @@
|
||||
<input id="character_name_pole" name="ch_name" class="text_pole" placeholder="Name this character" maxlength="50" value="" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<div id="avatar_div" class="avatar_div">
|
||||
<div id="avatar_div" class="avatar_div alignitemsflexstart justifySpaceBetween">
|
||||
<div id="avatar_div_div" class="avatar">
|
||||
<img id="avatar_load_preview" src="img/ai4.png" alt="avatar">
|
||||
</div>
|
||||
<div class="flex-container flexFlowColumn">
|
||||
<div class="form_create_bottom_buttons_block">
|
||||
<label for="add_avatar_button" class="menu_button fa-solid fa-file-image " title="Click to select a new avatar for this character">
|
||||
<input type="file" id="add_avatar_button" name="avatar" accept="image/png, image/jpeg, image/jpg, image/gif, image/bmp">
|
||||
@ -2342,8 +2362,10 @@
|
||||
</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 title="Token counts may be inaccurate and provided just for reference." id="result_info"> </div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
@ -2357,7 +2379,7 @@
|
||||
|
||||
<div id="description_div" class="marginBot5">
|
||||
<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>
|
||||
</a>
|
||||
</div>
|
||||
@ -2367,7 +2389,7 @@
|
||||
<div id="first_message_div" class="marginBot5 title_restorable">
|
||||
<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>
|
||||
</a>
|
||||
</span>
|
||||
@ -2412,7 +2434,7 @@
|
||||
<div class="">
|
||||
<div class="flex-container flexnowrap width100p whitespacenowrap">
|
||||
<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>
|
||||
</a>
|
||||
</div>
|
||||
@ -2597,7 +2619,7 @@
|
||||
<div id="personality_div">
|
||||
<h4>
|
||||
<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>
|
||||
<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>
|
||||
@ -2605,7 +2627,7 @@
|
||||
<div id="scenario_div">
|
||||
<h4>
|
||||
<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>
|
||||
</a>
|
||||
</h4>
|
||||
@ -2627,7 +2649,7 @@
|
||||
<div id="mes_example_div" class="flex-container flexFlowColumn">
|
||||
<div>
|
||||
<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>
|
||||
<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>
|
||||
@ -2643,7 +2665,7 @@
|
||||
<span id="ChatHistoryCharName"></span>
|
||||
<br>
|
||||
<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>
|
||||
<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">
|
||||
@ -2777,11 +2799,11 @@
|
||||
<form class="world_entry_form">
|
||||
<div class="inline-drawer wide100p">
|
||||
<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">
|
||||
<label for="key">
|
||||
<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>
|
||||
<textarea class="text_pole keyprimarytextpole" name="key" rows="1" placeholder="" maxlength="250"></textarea>
|
||||
</div>
|
||||
@ -2789,20 +2811,20 @@
|
||||
<label for="keysecondary">
|
||||
<h4><span data-i18n="Secondary Required Keywords">Secondary Required 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>
|
||||
<textarea class="text_pole keysecondarytextpole" name="keysecondary" rows="1" placeholder="(secondary keywords here)" maxlength="250"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></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_form_control">
|
||||
<label for="content ">
|
||||
<h4><span data-i18n="Content">Content</span></h4>
|
||||
<h5><span data-i18n="What this keyword should mean to the AI">What this keyword
|
||||
should mean to the AI</span></h5>
|
||||
<small><span data-i18n="What this keyword should mean to the AI">What this keyword
|
||||
should mean to the AI</span></small>
|
||||
</label>
|
||||
<textarea class="text_pole" name="content" rows="4" placeholder=""></textarea>
|
||||
</div>
|
||||
@ -2812,15 +2834,13 @@
|
||||
<div class="world_entry_form_control">
|
||||
<label for="comment">
|
||||
<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>
|
||||
<textarea class="text_pole" rows="1" name="comment" maxlength="250"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="world_entry_form_control world_entry_form_horizontal">
|
||||
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text flex1 ">
|
||||
<div class="flex-container flex1 justifySpaceBetween world_entry_form_horizontal">
|
||||
<div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text ">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="constant" />
|
||||
<span data-i18n="Constant">Constant</span>
|
||||
@ -2830,7 +2850,7 @@
|
||||
<span data-i18n="Selective">Selective</span>
|
||||
</label>
|
||||
</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>
|
||||
<label><input type="radio" name="position" value="0">
|
||||
<span data-i18n="Before Char">Before Char</span>
|
||||
@ -2842,19 +2862,13 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="world_entry_form_control wi-enter-footer-text flex1 flex-container flexNoGap ">
|
||||
<!-- world_entry_form_control -->
|
||||
<!-- <label for="order"> -->
|
||||
|
||||
<div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap ">
|
||||
Insertion Order
|
||||
<!-- Bigger number = inserted earlier -->
|
||||
|
||||
<!-- </label> -->
|
||||
<input class="text_pole" type="number" name="order" placeholder="" />
|
||||
<input class="text_pole wideMax100px" type="number" name="order" placeholder="" />
|
||||
</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">
|
||||
UID:
|
||||
|
||||
@ -2866,13 +2880,12 @@
|
||||
<span class="world_entry_form_token_counter">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="checkbox">
|
||||
<div class="wi-enter-footer-text">
|
||||
<label class="checkbox flex-container alignitemscenter">
|
||||
<input type="checkbox" name="disable" />
|
||||
<span data-i18n="Disable">Disable</span>
|
||||
</label>
|
||||
</div>
|
||||
<span class="world_popup_expander"> </span>
|
||||
<input class="menu_button delete_entry_button" type="submit" value="Delete Entry" />
|
||||
</div>
|
||||
</div>
|
||||
@ -3138,10 +3151,19 @@
|
||||
<div imgfile="" class="avatar">
|
||||
<img src="" alt="User Avatar">
|
||||
</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">
|
||||
<i class="fa-solid fa-user-edit"></i>
|
||||
</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">
|
||||
<i class="fa-solid fa-trash-alt"></i>
|
||||
</button>
|
||||
|
174
public/script.js
174
public/script.js
@ -1464,6 +1464,7 @@ function sendSystemMessage(type, text, extra = {}) {
|
||||
|
||||
if (type == system_message_types.HELP) {
|
||||
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) {
|
||||
@ -3928,8 +3929,11 @@ function appendUserAvatar(name) {
|
||||
const personaName = power_user.personas[name];
|
||||
if (personaName) {
|
||||
template.attr('title', personaName);
|
||||
} else {
|
||||
template.attr('title', '[Unnamed Persona]');
|
||||
}
|
||||
template.find('.avatar').attr('imgfile', name);
|
||||
template.toggleClass('default_persona', name === power_user.default_persona)
|
||||
template.find('img').attr('src', `User Avatars/${name}`);
|
||||
$("#user_avatar_block").append(template);
|
||||
highlightSelectedAvatar();
|
||||
@ -3950,9 +3954,9 @@ export function setUserName(value) {
|
||||
name1 = value;
|
||||
if (name1 === undefined || name1 == "")
|
||||
name1 = default_user_name;
|
||||
console.log(name1);
|
||||
console.log(`User name changed to ${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");
|
||||
} else {
|
||||
toastr.warning('You cannot change your name while sending a message', 'Warning');
|
||||
@ -3962,6 +3966,7 @@ export function setUserName(value) {
|
||||
export function autoSelectPersona(name) {
|
||||
for (const [key, value] of Object.entries(power_user.personas)) {
|
||||
if (value === name) {
|
||||
console.log(`Auto-selecting persona ${key} for name ${name}`);
|
||||
$(`.avatar[imgfile="${key}"]`).trigger('click');
|
||||
return;
|
||||
}
|
||||
@ -3978,15 +3983,38 @@ async function bindUserNameToPersona() {
|
||||
|
||||
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 || '');
|
||||
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;
|
||||
|
||||
// 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 {
|
||||
// If the user clicked ok, but didn't enter a name, delete the persona
|
||||
console.log(`Unbinding persona ${avatarId}`);
|
||||
delete power_user.personas[avatarId];
|
||||
}
|
||||
|
||||
saveSettingsDebounced();
|
||||
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() {
|
||||
user_avatar = $(this).attr("imgfile");
|
||||
reloadUserAvatar();
|
||||
@ -3997,10 +4025,10 @@ function setUserAvatar() {
|
||||
if (personaName && name1 !== personaName) {
|
||||
const lockedPersona = chat_metadata['persona'];
|
||||
if (lockedPersona && lockedPersona !== user_avatar) {
|
||||
toastr.warning(
|
||||
'Click the "Lock" to bind again. Otherwise, the selection will be reset when your reload the chat.',
|
||||
toastr.info(
|
||||
`To permanently set "${personaName}" as the selected persona, unlock and relock it using the "Lock" button. Otherwise, the selection resets upon reloading the chat.`,
|
||||
`This chat is locked to a different persona (${power_user.personas[lockedPersona]}).`,
|
||||
{ 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() {
|
||||
const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile');
|
||||
|
||||
@ -4017,6 +4096,7 @@ async function deleteUserAvatar() {
|
||||
}
|
||||
|
||||
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');
|
||||
return;
|
||||
}
|
||||
@ -4024,6 +4104,7 @@ async function deleteUserAvatar() {
|
||||
const confirm = await callPopup('Are you sure you want to delete this avatar?', 'confirm');
|
||||
|
||||
if (!confirm) {
|
||||
console.debug('User cancelled deleting avatar');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4036,46 +4117,96 @@ async function deleteUserAvatar() {
|
||||
});
|
||||
|
||||
if (request.ok) {
|
||||
console.log(`Deleted avatar ${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();
|
||||
await getUserAvatars();
|
||||
updateUserLockIcon();
|
||||
}
|
||||
}
|
||||
|
||||
function lockUserNameToChat() {
|
||||
if (chat_metadata['persona']) {
|
||||
console.log(`Unlocking persona for this chat ${chat_metadata['persona']}`);
|
||||
delete chat_metadata['persona'];
|
||||
saveMetadata();
|
||||
toastr.info('User persona is now unlocked for this chat. Click the "Lock" 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
chat_metadata['persona'] = user_avatar;
|
||||
saveMetadata();
|
||||
saveSettingsDebounced();
|
||||
console.log(`Locking persona for this chat ${user_avatar}`);
|
||||
toastr.success(`User persona is locked to ${name1} in this chat`);
|
||||
updateUserLockIcon();
|
||||
}
|
||||
|
||||
eventSource.on(event_types.CHAT_CHANGED, () => {
|
||||
// If persona is locked, select it
|
||||
if (chat_metadata['persona']) {
|
||||
// Find the avatar file
|
||||
const personaAvatar = $(`.avatar[imgfile="${chat_metadata['persona']}"]`).trigger('click');
|
||||
// Define a persona for this chat
|
||||
let chatPersona = '';
|
||||
|
||||
// Avatar missing (persona deleted)
|
||||
if (personaAvatar.length == 0) {
|
||||
console.warn('Persona avatar not found, unlocking persona');
|
||||
delete chat_metadata['persona'];
|
||||
if (chat_metadata['persona']) {
|
||||
// If persona is locked in chat metadata, select it
|
||||
console.log(`Using locked persona ${chat_metadata['persona']}`);
|
||||
chatPersona = chat_metadata['persona'];
|
||||
} else if (power_user.default_persona) {
|
||||
// If default persona is set, select it
|
||||
console.log(`Using default persona ${power_user.default_persona}`);
|
||||
chatPersona = power_user.default_persona;
|
||||
}
|
||||
|
||||
// No persona set: user current settings
|
||||
if (!chatPersona) {
|
||||
console.debug('No default or locked persona set for this chat');
|
||||
return;
|
||||
}
|
||||
|
||||
personaAvatar.trigger('click');
|
||||
// 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****************//
|
||||
@ -5024,7 +5155,7 @@ async function deleteMessageImage() {
|
||||
mesBlock.find('.mes_img_container').removeClass('img_extra');
|
||||
mesBlock.find('.mes_img').attr('src', '');
|
||||
saveChatConditional();
|
||||
updateVisibleDivs('#chat', false);
|
||||
/*updateVisibleDivs('#chat', false);*/
|
||||
}
|
||||
|
||||
function enlargeMessageImage() {
|
||||
@ -5704,9 +5835,10 @@ $(document).ready(function () {
|
||||
updateVisibleDivs('#rm_print_characters_block', true);
|
||||
}, 5));
|
||||
|
||||
$("#chat").on('scroll', debounce(() => {
|
||||
// This does not actually increase performance.
|
||||
/*$("#chat").on('scroll', debounce(() => {
|
||||
updateVisibleDivs('#chat', false);
|
||||
}, 10));
|
||||
}, 10));*/
|
||||
|
||||
let S_TAFocused = false;
|
||||
let S_TAPreviouslyFocused = false;
|
||||
@ -6958,6 +7090,8 @@ $(document).ready(function () {
|
||||
|
||||
$(document).on('click', '.bind_user_name', bindUserNameToPersona);
|
||||
$(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);
|
||||
|
||||
//**************************CHARACTER IMPORT EXPORT*************************//
|
||||
|
@ -260,16 +260,23 @@ export function RA_CountCharTokens() {
|
||||
(power_user.pin_examples ? characters[this_chid].mes_example : ''),
|
||||
].join('\n').replace(/\r/gm, '').trim();
|
||||
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
|
||||
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 {
|
||||
$("#result_info").html(`
|
||||
<span class="neutral_warning">${count_tokens}</span> Tokens (<span class="neutral_warning">${perm_tokens}</span><span> Permanent Tokens)
|
||||
<br>
|
||||
<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>`);
|
||||
<div class="flex-container flexFlowColumn alignitemscenter">
|
||||
<div class="flex-container flexnowrap flexNoGap">
|
||||
<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
|
||||
}
|
||||
//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";
|
||||
export {
|
||||
getContext,
|
||||
@ -69,6 +69,20 @@ const getContext = () => window['SillyTavern'].getContext();
|
||||
const getApiUrl = () => extension_settings.apiUrl;
|
||||
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) {
|
||||
if (!args) {
|
||||
args = {}
|
||||
@ -219,7 +233,7 @@ function autoConnectInputHandler() {
|
||||
|
||||
function addExtensionsButtonAndMenu() {
|
||||
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>`;
|
||||
|
||||
$(document.body).append(extensionsMenuHTML);
|
||||
|
@ -166,5 +166,5 @@ $(document).ready(function () {
|
||||
setInterval(moduleWorker, UPDATE_INTERVAL);
|
||||
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('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();
|
||||
|
||||
let popper = Popper.createPopper(button.get(0), dropdown.get(0), {
|
||||
placement: 'bottom',
|
||||
placement: 'top',
|
||||
});
|
||||
|
||||
$(document).on('click touchend', function (e) {
|
||||
@ -68,10 +68,10 @@ function addDiceRollButton() {
|
||||
if (target.is(button) && !dropdown.is(":visible")) {
|
||||
e.preventDefault();
|
||||
|
||||
dropdown.show(200);
|
||||
dropdown.fadeIn(250);
|
||||
popper.update();
|
||||
} 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 { ModuleWorkerWrapper, extension_settings, getContext, saveMetadataDebounced } from "../../extensions.js";
|
||||
import { registerSlashCommand } from "../../slash-commands.js";
|
||||
@ -66,6 +73,7 @@ function setNotePositionCommand(_, text) {
|
||||
|
||||
async function onExtensionFloatingPromptInput() {
|
||||
chat_metadata[metadata_keys.prompt] = $(this).val();
|
||||
$('#extension_floating_prompt_token_counter').text(getTokenCount(chat_metadata[metadata_keys.prompt]));
|
||||
saveMetadataDebounced();
|
||||
}
|
||||
|
||||
@ -93,6 +101,7 @@ async function onExtensionFloatingPositionInput(e) {
|
||||
|
||||
function onExtensionFloatingDefaultInput() {
|
||||
extension_settings.note.default = $(this).val();
|
||||
$('#extension_floating_default_token_counter').text(getTokenCount(extension_settings.note.default));
|
||||
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 addExtensionsSettings() {
|
||||
const settingsHtml = `
|
||||
@ -195,6 +211,7 @@ function onANMenuItemClick() {
|
||||
</small>
|
||||
|
||||
<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">
|
||||
<label>
|
||||
@ -228,6 +245,7 @@ function onANMenuItemClick() {
|
||||
|
||||
<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>
|
||||
<div class="extension_token_counter">Tokens: <span id="extension_floating_default_token_counter">0</small></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('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);
|
||||
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);
|
||||
})();
|
||||
|
@ -31,6 +31,12 @@
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.extension_token_counter {
|
||||
font-size: calc(var(--mainFontSize) * 0.9);
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.floating_prompt_settings textarea {
|
||||
font-size: calc(var(--mainFontSize) * 0.9);
|
||||
line-height: 1.2;
|
||||
|
@ -547,7 +547,7 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
// if swipe - see if message changed
|
||||
@ -1418,6 +1418,14 @@ function onGroupScenarioRemoveClick() {
|
||||
$(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() {
|
||||
if (groupAutoModeAbortController) {
|
||||
groupAutoModeAbortController.abort();
|
||||
@ -1440,4 +1448,5 @@ jQuery(() => {
|
||||
is_group_automode_enabled = value;
|
||||
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.`;
|
||||
|
||||
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 poe_settings = {
|
||||
@ -265,7 +265,7 @@ async function generatePoe(type, finalPrompt, signal) {
|
||||
const isQuiet = type === 'quiet';
|
||||
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');
|
||||
const result = await sendChunkedMessage(finalPrompt, !isQuiet, signal)
|
||||
reply = result.reply;
|
||||
|
@ -146,6 +146,7 @@ let power_user = {
|
||||
},
|
||||
|
||||
personas: {},
|
||||
default_persona: null,
|
||||
};
|
||||
|
||||
let themes = [];
|
||||
|
@ -98,7 +98,7 @@ const getSlashCommandsHelp = parser.getHelpString.bind(parser);
|
||||
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('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('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);
|
||||
@ -262,6 +262,7 @@ function executeSlashCommands(text) {
|
||||
continue;
|
||||
}
|
||||
|
||||
console.debug('Slash command executing:', result);
|
||||
result.command.callback(result.args, result.value);
|
||||
|
||||
if (result.command.interruptsGeneration) {
|
||||
|
110
public/style.css
110
public/style.css
@ -34,6 +34,7 @@
|
||||
--orangered: rgb(255, 90, 0);
|
||||
--greyCAIbg: rgb(36, 36, 37);
|
||||
--ivory: rgb(220, 220, 210);
|
||||
--golden: rgba(212, 175, 55, 1);
|
||||
|
||||
|
||||
/*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));
|
||||
margin: 5px 0;
|
||||
height: 1px;
|
||||
min-height: 1px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@ -895,6 +897,10 @@ select {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.margin5 {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#description_textarea,
|
||||
#firstmessage_textarea {
|
||||
height: -webkit-fill-available;
|
||||
@ -993,10 +999,17 @@ input[type="file"] {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
#right-nav-panel-tabs .right_menu_button {
|
||||
#right-nav-panel-tabs .right_menu_button,
|
||||
#CharListButtonAndHotSwaps .right_menu_button {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
#chartokenwarning.menu_button {
|
||||
font-size: unset;
|
||||
height: fit-content;
|
||||
aspect-ratio: unset;
|
||||
}
|
||||
|
||||
/* ##################################################################### */
|
||||
/* Right Panel's Upper Tabs */
|
||||
/* ##################################################################### */
|
||||
@ -1239,7 +1252,8 @@ select option:not(:checked) {
|
||||
}
|
||||
|
||||
#form_character_search_form .menu_button,
|
||||
#GroupFavDelOkBack .menu_button {
|
||||
#GroupFavDelOkBack .menu_button,
|
||||
.avatar-container .menu_button {
|
||||
margin: 0;
|
||||
height: fit-content;
|
||||
padding: 5px;
|
||||
@ -1326,6 +1340,10 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
width: calc(100% - 70px);
|
||||
}
|
||||
|
||||
.wideMax100px {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.widthUnset {
|
||||
width: unset;
|
||||
}
|
||||
@ -1432,7 +1450,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
width: 100%;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 6px;
|
||||
/* margin-bottom: 6px; */
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@ -1446,7 +1464,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
display: flex;
|
||||
flex: 0 0 100%;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 4px;
|
||||
/* margin-bottom: 4px; */
|
||||
}
|
||||
|
||||
|
||||
@ -1529,21 +1547,35 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
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 {
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.avatar_div .avatar {
|
||||
margin-left: 4px;
|
||||
/* margin-left: 4px;
|
||||
margin-right: 10px;
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
width: 70px; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@ -1612,7 +1644,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
}
|
||||
|
||||
#result_info {
|
||||
font-size: calc(var(--mainFontSize) - 0.2rem);
|
||||
font-size: calc(var(--mainFontSize) - 0.1rem);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@ -1885,27 +1917,6 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
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 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -1980,7 +1991,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
.world_entry_form_control {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 10px;
|
||||
/* margin: 0 10px; */
|
||||
}
|
||||
|
||||
.world_entry_thin_controls {
|
||||
@ -1998,7 +2009,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
|
||||
.world_entry_form_control label h4 {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0.5rem;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.world_entry_form_control label h5 {
|
||||
@ -2010,12 +2021,13 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
height: auto;
|
||||
/* width: auto; */
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.world_entry_form_control.world_entry_form_horizontal {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
/* margin-top: 5px; */
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@ -2077,6 +2089,11 @@ input[type=search]:focus::-webkit-search-cancel-button {
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
/* Override toastr default styles */
|
||||
body #toast-container>div {
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
#dialogue_del_mes {
|
||||
display: none;
|
||||
}
|
||||
@ -2152,6 +2169,15 @@ input[type='checkbox']:not(#nav-toggle):not(#rm_button_panel_pin):not(#lm_button
|
||||
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 {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
@ -2253,8 +2279,8 @@ input[type="range"]::-webkit-slider-thumb {
|
||||
/*Notes '?' links*/
|
||||
|
||||
.note-link-span {
|
||||
color: var(--sienna);
|
||||
border: 1px solid var(--sienna);
|
||||
color: var(--SmartThemeQuoteColor);
|
||||
border: 1px solid var(--SmartThemeQuoteColor);
|
||||
border-radius: 10px;
|
||||
line-height: var(--mainFontSize);
|
||||
font-size: var(--mainFontSize);
|
||||
@ -3852,6 +3878,10 @@ toolcool-color-picker {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.margin0auto {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.margin-r5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
@ -4321,7 +4351,7 @@ body.waifuMode #avatar_zoom_popup {
|
||||
}
|
||||
|
||||
.world_entry_form_control.world_entry_form_horizontal {
|
||||
flex-direction: column;
|
||||
/* flex-direction: column; */
|
||||
align-items: flex-start;
|
||||
row-gap: 0.5rem;
|
||||
}
|
||||
@ -4462,9 +4492,9 @@ body.waifuMode #avatar_zoom_popup {
|
||||
font-size: calc(var(--mainFontSize) - .1rem);
|
||||
}
|
||||
|
||||
.avatar_div {
|
||||
/* .avatar_div {
|
||||
margin-top: 5px;
|
||||
}
|
||||
} */
|
||||
|
||||
#character_popup {
|
||||
width: 100%;
|
||||
@ -4482,7 +4512,7 @@ body.waifuMode #avatar_zoom_popup {
|
||||
}
|
||||
|
||||
.drawer25pWidth {
|
||||
flex-basis: max(calc(100% / 4 - 10px), 200px);
|
||||
flex-basis: max(calc(100% / 4 - 10px), 190px);
|
||||
}
|
||||
|
||||
.expression-holder {
|
||||
@ -4550,7 +4580,7 @@ body.waifuMode #avatar_zoom_popup {
|
||||
|
||||
@media screen and (max-width: 450px) {
|
||||
.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,
|
||||
};
|
||||
|
||||
const MAX_RETRIES = 10;
|
||||
const delayAmount = 3000;
|
||||
|
||||
const MAX_RETRIES = 50;
|
||||
const delayAmount = 2500;
|
||||
let fetch, url, response;
|
||||
for (let i = 0; i < MAX_RETRIES; i++) {
|
||||
try {
|
||||
@ -420,15 +419,23 @@ app.post("/generate", jsonParser, async function (request, response_generate = r
|
||||
}
|
||||
} catch (error) {
|
||||
// response
|
||||
switch (error.statusCode) {
|
||||
switch (error?.status) {
|
||||
case 403:
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
if ('status' in error) {
|
||||
console.log('Status Code from Kobold:', error.status);
|
||||
}
|
||||
return response_generate.send({ error: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Max retries exceeded. Giving up.');
|
||||
return response_generate.send({ error: true });
|
||||
});
|
||||
|
||||
//************** Text generation web UI
|
||||
@ -685,11 +692,11 @@ function getVersion() {
|
||||
pkgVersion = pkgJson.version;
|
||||
if (!process.pkg && commandExistsSync('git')) {
|
||||
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();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -2421,7 +2428,7 @@ app.post('/generate_poe', jsonParser, async (request, response) => {
|
||||
if (streaming) {
|
||||
try {
|
||||
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) {
|
||||
response.writeHead(200, {
|
||||
'Content-Type': 'text/plain;charset=utf-8',
|
||||
@ -2454,7 +2461,7 @@ app.post('/generate_poe', jsonParser, async (request, response) => {
|
||||
try {
|
||||
let reply;
|
||||
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;
|
||||
messageId = mes.messageId;
|
||||
}
|
||||
@ -3151,7 +3158,7 @@ async function postAsync(url, args) {
|
||||
return data;
|
||||
}
|
||||
|
||||
throw new Error(response);
|
||||
throw response;
|
||||
}
|
||||
|
||||
function getAsync(url, args) {
|
||||
@ -3179,6 +3186,10 @@ const autorunUrl = new URL(
|
||||
);
|
||||
|
||||
const setupTasks = async function () {
|
||||
const version = getVersion();
|
||||
|
||||
console.log(`SillyTavern ${version.pkgVersion}` + (version.gitBranch ? ` '${version.gitBranch}' (${version.gitRevision})` : ''));
|
||||
|
||||
migrateSecrets();
|
||||
ensurePublicDirectoriesExist();
|
||||
await ensureThumbnailCache();
|
||||
@ -3196,6 +3207,10 @@ const setupTasks = async function () {
|
||||
|
||||
if (autorun) open(autorunUrl.toString());
|
||||
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) {
|
||||
|
@ -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();
|
||||
|
||||
if (this.auto_reconnect) {
|
||||
|
Reference in New Issue
Block a user