Merge pull request #2580 from SillyTavern/staging Staging

eac2e3d81e128c61299c94ef6c9dd1a8fd87a8c1

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
12 files changed, +127 -167Ignore whitespace
public/css/extensions-panel.css+2 -1
@@ -7,7 +7,8 @@
7 background-color: green;7 background-color: green;
8}8}
99
10.extensions_block input[type="checkbox"] {10.extensions_block input[type="checkbox"],
11.extensions_block input[type="radio"] {
11 margin-left: 10px;12 margin-left: 10px;
12 margin-right: 10px;13 margin-right: 10px;
13}14}
public/css/tags.css+6 -6
@@ -209,20 +209,20 @@
209 opacity: 1;209 opacity: 1;
210}210}
211211
212.tag_as_folder {212.tag_as_folder.right_menu_button {
213 filter: brightness(75%) saturate(0.6);213 filter: brightness(75%) saturate(0.6);
214}214}
215215
216.tag_as_folder:hover,216.tag_as_folder.right_menu_button:hover,
217.tag_as_folder.flash {217.tag_as_folder.right_menu_button.flash {
218 filter: brightness(150%) saturate(0.6) !important;218 filter: brightness(150%) saturate(0.6);
219}219}
220220
221.tag_as_folder.no_folder {221.tag_as_folder.right_menu_button.no_folder {
222 filter: brightness(25%) saturate(0.25);222 filter: brightness(25%) saturate(0.25);
223}223}
224224
225.tag_as_folder .tag_folder_indicator {225.tag_as_folder.right_menu_button .tag_folder_indicator {
226 position: absolute;226 position: absolute;
227 top: calc(var(--mainFontSize) * -0.5);227 top: calc(var(--mainFontSize) * -0.5);
228 right: calc(var(--mainFontSize) * -0.5);228 right: calc(var(--mainFontSize) * -0.5);
public/index.html+1 -1
@@ -4026,7 +4026,7 @@
4026 <input type="range" id="smooth_streaming_speed" name="smooth_streaming_speed" min="0" max="100" step="10" value="50">4026 <input type="range" id="smooth_streaming_speed" name="smooth_streaming_speed" min="0" max="100" step="10" value="50">
4027 <div class="slider_hint">4027 <div class="slider_hint">
4028 <span data-i18n="Slow">Slow</span>4028 <span data-i18n="Slow">Slow</span>
4029 <span data-i18n=""></span>4029 <span></span>
4030 <span data-i18n="Fast">Fast</span>4030 <span data-i18n="Fast">Fast</span>
4031 </div>4031 </div>
4032 </div>4032 </div>
public/locales/zh-cn.json+17 -3
@@ -217,9 +217,11 @@
217 "Character Names Behavior": "角色名称行为",217 "Character Names Behavior": "角色名称行为",
218 "Helps the model to associate messages with characters.": "有助于模型将消息与角色关联起来。",218 "Helps the model to associate messages with characters.": "有助于模型将消息与角色关联起来。",
219 "None": "无",219 "None": "无",
220 "character_names_none": "不添加角色名称前缀。在群聊中可能导致错误行为,谨慎勾选。",
221 "Never add character names.": "不添加角色名称。",
220 "character_names_default": "群聊和过去的角色除外。否则,请确保在提示词中提供了姓名。",222 "character_names_default": "群聊和过去的角色除外。否则,请确保在提示词中提供了姓名。",
221 "Don't add character names.": "不添加角色名称。",223 "Don't add character names unless necessary.": "如非必要,否则不添加角色名称。",
222 "Completion": "补全对象",224 "Completion Object": "补全对象",
223 "character_names_completion": "适用限制:仅限拉丁字母数字和下划线。不适用于所有补全源,尤其是:Claude、MistralAI、Google。",225 "character_names_completion": "适用限制:仅限拉丁字母数字和下划线。不适用于所有补全源,尤其是:Claude、MistralAI、Google。",
224 "Add character names to completion objects.": "在补全对象中添加角色名称。",226 "Add character names to completion objects.": "在补全对象中添加角色名称。",
225 "Message Content": "消息内容",227 "Message Content": "消息内容",
@@ -489,6 +491,10 @@
489 "First Assistant Prefix": "第一个助理前缀",491 "First Assistant Prefix": "第一个助理前缀",
490 "instruct_last_output_sequence": "插入到最后一条助手消息之前或作为生成 AI 回复时的最后一行提示词(中立/系统角色除外)。",492 "instruct_last_output_sequence": "插入到最后一条助手消息之前或作为生成 AI 回复时的最后一行提示词(中立/系统角色除外)。",
491 "Last Assistant Prefix": "最后一个助理前缀",493 "Last Assistant Prefix": "最后一个助理前缀",
494 "Inserted before the first User's message.": "插入在第一个用户的消息之前。",
495 "First User Prefix": "第一个用户前缀",
496 "instruct_last_input_sequence": "插入到最后一条用户消息之前。",
497 "Last User Prefix": "上次用户前缀",
492 "Will be inserted as a last prompt line when using system/neutral generation.": "当使用系统/中性生成时将作为最后的一行提示词插入。",498 "Will be inserted as a last prompt line when using system/neutral generation.": "当使用系统/中性生成时将作为最后的一行提示词插入。",
493 "System Instruction Prefix": "系统指令前缀",499 "System Instruction Prefix": "系统指令前缀",
494 "If a stop sequence is generated, everything past it will be removed from the output (inclusive).": "如果生成了停止序列,则该序列之后的所有内容都将从输出中删除(包括在内)。",500 "If a stop sequence is generated, everything past it will be removed from the output (inclusive).": "如果生成了停止序列,则该序列之后的所有内容都将从输出中删除(包括在内)。",
@@ -555,7 +561,7 @@
555 "Close all Entries": "关闭所有条目",561 "Close all Entries": "关闭所有条目",
556 "New Entry": "新条目",562 "New Entry": "新条目",
557 "Fill empty Memo/Titles with Keywords": "使用关键字填充空的备忘录/标题",563 "Fill empty Memo/Titles with Keywords": "使用关键字填充空的备忘录/标题",
558 "Apply custom sorting as Order": "应用自定义排序作为顺序",564 "Apply current sorting as Order": "应用当前排序作为顺序",
559 "Import World Info": "导入世界书",565 "Import World Info": "导入世界书",
560 "Export World Info": "导出世界书",566 "Export World Info": "导出世界书",
561 "Duplicate World Info": "复制世界书",567 "Duplicate World Info": "复制世界书",
@@ -1187,6 +1193,7 @@
1187 "Bind user name to that avatar": "将用户名称绑定到该头像",1193 "Bind user name to that avatar": "将用户名称绑定到该头像",
1188 "Change persona image": "更改用户角色头像",1194 "Change persona image": "更改用户角色头像",
1189 "Select this as default persona for the new chats.": "选择此项作为新聊天的默认用户角色。",1195 "Select this as default persona for the new chats.": "选择此项作为新聊天的默认用户角色。",
1196 "Duplicate persona": "复制用户角色",
1190 "Delete persona": "删除用户角色",1197 "Delete persona": "删除用户角色",
1191 "These characters are the winners of character design contests and have outstandable quality.": "这些角色都是角色设计大赛的获奖者,品质非常出色。",1198 "These characters are the winners of character design contests and have outstandable quality.": "这些角色都是角色设计大赛的获奖者,品质非常出色。",
1192 "Contest Winners": "比赛获胜者",1199 "Contest Winners": "比赛获胜者",
@@ -1327,6 +1334,10 @@
1327 "ext_sum_injection_template": "插入模板",1334 "ext_sum_injection_template": "插入模板",
1328 "ext_sum_memory_template_placeholder": "{{summary}} 将解析当前摘要内容。",1335 "ext_sum_memory_template_placeholder": "{{summary}} 将解析当前摘要内容。",
1329 "ext_sum_injection_position": "插入位置",1336 "ext_sum_injection_position": "插入位置",
1337 "ext_sum_include_wi_scan_desc": "在 WI 扫描中包括最新摘要。",
1338 "ext_sum_include_wi_scan": "纳入世界信息扫描",
1339 "None (not injected)": "无(未注入)",
1340 "ext_sum_injection_position_none": "摘要不会被注入到提示中。您仍然可以通过 {{summary}} 宏访问它。",
1330 "How many messages before the current end of the chat.": "当前聊天结束前还有多少条消息。",1341 "How many messages before the current end of the chat.": "当前聊天结束前还有多少条消息。",
1331 "Labels and Message": "标签和信息",1342 "Labels and Message": "标签和信息",
1332 "Label": "标签",1343 "Label": "标签",
@@ -1757,6 +1768,8 @@
1757 "help_macros_56": "指示系统指令前缀",1768 "help_macros_56": "指示系统指令前缀",
1758 "help_macros_57": "指示第一个用户消息填充器",1769 "help_macros_57": "指示第一个用户消息填充器",
1759 "help_macros_58": "指示停止顺序",1770 "help_macros_58": "指示停止顺序",
1771 "help_macros_first_user": "指示用户第一个输入序列",
1772 "help_macros_last_user": "指示用户最后输入序列",
1760 "Chat variables Macros:": "聊天变量宏:",1773 "Chat variables Macros:": "聊天变量宏:",
1761 "Local variables = unique to the current chat": "局部变量 = 当前聊天所独有",1774 "Local variables = unique to the current chat": "局部变量 = 当前聊天所独有",
1762 "Global variables = works in any chat for any character": "全局变量 = 适用于任何角色的任何聊天",1775 "Global variables = works in any chat for any character": "全局变量 = 适用于任何角色的任何聊天",
@@ -1794,6 +1807,7 @@
1794 "Record a snapshot of your current settings.": "记录当前设置的快照。",1807 "Record a snapshot of your current settings.": "记录当前设置的快照。",
1795 "Make a Snapshot": "制作快照",1808 "Make a Snapshot": "制作快照",
1796 "Restore this snapshot": "恢复此快照",1809 "Restore this snapshot": "恢复此快照",
1810 "Download Model": "下载模型",
1797 "Downloader Options": "下载器选项",1811 "Downloader Options": "下载器选项",
1798 "Extra parameters for downloading/HuggingFace API": "下载/HuggingFace API 的额外参数。如果不确定,请将其留空。",1812 "Extra parameters for downloading/HuggingFace API": "下载/HuggingFace API 的额外参数。如果不确定,请将其留空。",
1799 "Revision": "修订",1813 "Revision": "修订",
public/script.js+30 -120
@@ -570,6 +570,7 @@ export const system_message_types = {
570 * @enum {number} Extension prompt types570 * @enum {number} Extension prompt types
571 */571 */
572export const extension_prompt_types = {572export const extension_prompt_types = {
573 NONE: -1,
573 IN_PROMPT: 0,574 IN_PROMPT: 0,
574 IN_CHAT: 1,575 IN_CHAT: 1,
575 BEFORE_PROMPT: 2,576 BEFORE_PROMPT: 2,
@@ -929,10 +930,17 @@ async function firstLoadInit() {
929 initCfg();930 initCfg();
930 initLogprobs();931 initLogprobs();
931 doDailyExtensionUpdatesCheck();932 doDailyExtensionUpdatesCheck();
932 hideLoader();933 await hideLoader();
934 await fixViewport();
933 await eventSource.emit(event_types.APP_READY);935 await eventSource.emit(event_types.APP_READY);
934}936}
935937
938async function fixViewport() {
939 document.body.style.position = 'absolute';
940 await delay(1);
941 document.body.style.position = '';
942}
943
936function cancelStatusCheck() {944function cancelStatusCheck() {
937 abortStatusCheck?.abort();945 abortStatusCheck?.abort();
938 abortStatusCheck = new AbortController();946 abortStatusCheck = new AbortController();
@@ -8302,6 +8310,7 @@ const swipe_right = () => {
8302};8310};
83038311
8304const CONNECT_API_MAP = {8312const CONNECT_API_MAP = {
8313 // Default APIs not contined inside text gen / chat gen
8305 'kobold': {8314 'kobold': {
8306 selected: 'kobold',8315 selected: 'kobold',
8307 button: '#api_button',8316 button: '#api_button',
@@ -8313,147 +8322,48 @@ const CONNECT_API_MAP = {
8313 selected: 'novel',8322 selected: 'novel',
8314 button: '#api_button_novel',8323 button: '#api_button_novel',
8315 },8324 },
8316 'ooba': {8325 // KoboldCpp alias
8317 selected: 'textgenerationwebui',
8318 button: '#api_button_textgenerationwebui',
8319 type: textgen_types.OOBA,
8320 },
8321 'tabby': {
8322 selected: 'textgenerationwebui',
8323 button: '#api_button_textgenerationwebui',
8324 type: textgen_types.TABBY,
8325 },
8326 'llamacpp': {
8327 selected: 'textgenerationwebui',
8328 button: '#api_button_textgenerationwebui',
8329 type: textgen_types.LLAMACPP,
8330 },
8331 'ollama': {
8332 selected: 'textgenerationwebui',
8333 button: '#api_button_textgenerationwebui',
8334 type: textgen_types.OLLAMA,
8335 },
8336 'mancer': {
8337 selected: 'textgenerationwebui',
8338 button: '#api_button_textgenerationwebui',
8339 type: textgen_types.MANCER,
8340 },
8341 'vllm': {
8342 selected: 'textgenerationwebui',
8343 button: '#api_button_textgenerationwebui',
8344 type: textgen_types.VLLM,
8345 },
8346 'aphrodite': {
8347 selected: 'textgenerationwebui',
8348 button: '#api_button_textgenerationwebui',
8349 type: textgen_types.APHRODITE,
8350 },
8351 'koboldcpp': {
8352 selected: 'textgenerationwebui',
8353 button: '#api_button_textgenerationwebui',
8354 type: textgen_types.KOBOLDCPP,
8355 },
8356 'kcpp': {8326 'kcpp': {
8357 selected: 'textgenerationwebui',8327 selected: 'textgenerationwebui',
8358 button: '#api_button_textgenerationwebui',8328 button: '#api_button_textgenerationwebui',
8359 type: textgen_types.KOBOLDCPP,8329 type: textgen_types.KOBOLDCPP,
8360 },8330 },
8361 'togetherai': {8331 // OpenAI alias
8362 selected: 'textgenerationwebui',
8363 button: '#api_button_textgenerationwebui',
8364 type: textgen_types.TOGETHERAI,
8365 },
8366 'openai': {
8367 selected: 'openai',
8368 button: '#api_button_openai',
8369 source: chat_completion_sources.OPENAI,
8370 },
8371 'oai': {8332 'oai': {
8372 selected: 'openai',8333 selected: 'openai',
8373 button: '#api_button_openai',8334 button: '#api_button_openai',
8374 source: chat_completion_sources.OPENAI,8335 source: chat_completion_sources.OPENAI,
8375 },8336 },
8376 'claude': {8337 // OpenRouter special naming, to differentiate between chat comp and text comp
8377 selected: 'openai',
8378 button: '#api_button_openai',
8379 source: chat_completion_sources.CLAUDE,
8380 },
8381 'windowai': {
8382 selected: 'openai',
8383 button: '#api_button_openai',
8384 source: chat_completion_sources.WINDOWAI,
8385 },
8386 'openrouter': {8338 'openrouter': {
8387 selected: 'openai',8339 selected: 'openai',
8388 button: '#api_button_openai',8340 button: '#api_button_openai',
8389 source: chat_completion_sources.OPENROUTER,8341 source: chat_completion_sources.OPENROUTER,
8390 },8342 },
8391 'scale': {
8392 selected: 'openai',
8393 button: '#api_button_openai',
8394 source: chat_completion_sources.SCALE,
8395 },
8396 'ai21': {
8397 selected: 'openai',
8398 button: '#api_button_openai',
8399 source: chat_completion_sources.AI21,
8400 },
8401 'makersuite': {
8402 selected: 'openai',
8403 button: '#api_button_openai',
8404 source: chat_completion_sources.MAKERSUITE,
8405 },
8406 'mistralai': {
8407 selected: 'openai',
8408 button: '#api_button_openai',
8409 source: chat_completion_sources.MISTRALAI,
8410 },
8411 'custom': {
8412 selected: 'openai',
8413 button: '#api_button_openai',
8414 source: chat_completion_sources.CUSTOM,
8415 },
8416 'cohere': {
8417 selected: 'openai',
8418 button: '#api_button_openai',
8419 source: chat_completion_sources.COHERE,
8420 },
8421 'perplexity': {
8422 selected: 'openai',
8423 button: '#api_button_openai',
8424 source: chat_completion_sources.PERPLEXITY,
8425 },
8426 'groq': {
8427 selected: 'openai',
8428 button: '#api_button_openai',
8429 source: chat_completion_sources.GROQ,
8430 },
8431 '01ai': {
8432 selected: 'openai',
8433 button: '#api_button_openai',
8434 source: chat_completion_sources.ZEROONEAI,
8435 },
8436 'infermaticai': {
8437 selected: 'textgenerationwebui',
8438 button: '#api_button_textgenerationwebui',
8439 type: textgen_types.INFERMATICAI,
8440 },
8441 'dreamgen': {
8442 selected: 'textgenerationwebui',
8443 button: '#api_button_textgenerationwebui',
8444 type: textgen_types.DREAMGEN,
8445 },
8446 'openrouter-text': {8343 'openrouter-text': {
8447 selected: 'textgenerationwebui',8344 selected: 'textgenerationwebui',
8448 button: '#api_button_textgenerationwebui',8345 button: '#api_button_textgenerationwebui',
8449 type: textgen_types.OPENROUTER,8346 type: textgen_types.OPENROUTER,
8450 },8347 },
8451 'huggingface': {8348};
8349
8350// Fill connections map from textgen_types and chat_completion_sources
8351for (const textGenType of Object.values(textgen_types)) {
8352 if (CONNECT_API_MAP[textGenType]) continue;
8353 CONNECT_API_MAP[textGenType] = {
8452 selected: 'textgenerationwebui',8354 selected: 'textgenerationwebui',
8453 button: '#api_button_textgenerationwebui',8355 button: '#api_button_textgenerationwebui',
8454 type: textgen_types.HUGGINGFACE,8356 type: textGenType,
8455 },8357 };
8456};8358}
8359for (const chatCompletionSource of Object.values(chat_completion_sources)) {
8360 if (CONNECT_API_MAP[chatCompletionSource]) continue;
8361 CONNECT_API_MAP[chatCompletionSource] = {
8362 selected: 'openai',
8363 button: '#api_button_openai',
8364 source: chatCompletionSource,
8365 };
8366}
84578367
8458async function selectContextCallback(_, name) {8368async function selectContextCallback(_, name) {
8459 if (!name) {8369 if (!name) {
public/scripts/extensions/memory/index.js+13 -2
@@ -14,6 +14,7 @@ import {
14 substituteParamsExtended,14 substituteParamsExtended,
15 generateRaw,15 generateRaw,
16 getMaxContextSize,16 getMaxContextSize,
17 setExtensionPrompt,
17} from '../../../script.js';18} from '../../../script.js';
18import { is_group_generating, selected_group } from '../../group-chats.js';19import { is_group_generating, selected_group } from '../../group-chats.js';
19import { loadMovingUIState } from '../../power-user.js';20import { loadMovingUIState } from '../../power-user.js';
@@ -73,6 +74,7 @@ const defaultSettings = {
73 template: defaultTemplate,74 template: defaultTemplate,
74 position: extension_prompt_types.IN_PROMPT,75 position: extension_prompt_types.IN_PROMPT,
75 role: extension_prompt_roles.SYSTEM,76 role: extension_prompt_roles.SYSTEM,
77 scan: false,
76 depth: 2,78 depth: 2,
77 promptWords: 200,79 promptWords: 200,
78 promptMinWords: 25,80 promptMinWords: 25,
@@ -122,6 +124,7 @@ function loadSettings() {
122 $(`input[name="memory_prompt_builder"][value="${extension_settings.memory.prompt_builder}"]`).prop('checked', true).trigger('input');124 $(`input[name="memory_prompt_builder"][value="${extension_settings.memory.prompt_builder}"]`).prop('checked', true).trigger('input');
123 $('#memory_override_response_length').val(extension_settings.memory.overrideResponseLength).trigger('input');125 $('#memory_override_response_length').val(extension_settings.memory.overrideResponseLength).trigger('input');
124 $('#memory_max_messages_per_request').val(extension_settings.memory.maxMessagesPerRequest).trigger('input');126 $('#memory_max_messages_per_request').val(extension_settings.memory.maxMessagesPerRequest).trigger('input');
127 $('#memory_include_wi_scan').prop('checked', extension_settings.memory.scan).trigger('input');
125 switchSourceControls(extension_settings.memory.source);128 switchSourceControls(extension_settings.memory.source);
126}129}
127130
@@ -279,6 +282,13 @@ function onMemoryPositionChange(e) {
279 saveSettingsDebounced();282 saveSettingsDebounced();
280}283}
281284
285function onMemoryIncludeWIScanInput() {
286 const value = !!$(this).prop('checked');
287 extension_settings.memory.scan = value;
288 reinsertMemory();
289 saveSettingsDebounced();
290}
291
282function onMemoryPromptWordsForceInput() {292function onMemoryPromptWordsForceInput() {
283 const value = $(this).val();293 const value = $(this).val();
284 extension_settings.memory.promptForceWords = Number(value);294 extension_settings.memory.promptForceWords = Number(value);
@@ -800,8 +810,7 @@ function reinsertMemory() {
800 * @param {number|null} index Index of the chat message to save the summary to. If null, the pre-last message is used.810 * @param {number|null} index Index of the chat message to save the summary to. If null, the pre-last message is used.
801 */811 */
802function setMemoryContext(value, saveToMessage, index = null) {812function setMemoryContext(value, saveToMessage, index = null) {
803 const context = getContext();813 setExtensionPrompt(MODULE_NAME, formatMemoryValue(value), extension_settings.memory.position, extension_settings.memory.depth, extension_settings.memory.scan, extension_settings.memory.role);
804 context.setExtensionPrompt(MODULE_NAME, formatMemoryValue(value), extension_settings.memory.position, extension_settings.memory.depth, false, extension_settings.memory.role);
805 $('#memory_contents').val(value);814 $('#memory_contents').val(value);
806815
807 const summaryLog = value816 const summaryLog = value
@@ -809,6 +818,7 @@ function setMemoryContext(value, saveToMessage, index = null) {
809 : 'Summary has no content';818 : 'Summary has no content';
810 console.debug(summaryLog);819 console.debug(summaryLog);
811820
821 const context = getContext();
812 if (saveToMessage && context.chat.length) {822 if (saveToMessage && context.chat.length) {
813 const idx = index ?? context.chat.length - 2;823 const idx = index ?? context.chat.length - 2;
814 const mes = context.chat[idx < 0 ? 0 : idx];824 const mes = context.chat[idx < 0 ? 0 : idx];
@@ -894,6 +904,7 @@ function setupListeners() {
894 $('#memory_prompt_words_auto').off('click').on('click', onPromptForceWordsAutoClick);904 $('#memory_prompt_words_auto').off('click').on('click', onPromptForceWordsAutoClick);
895 $('#memory_override_response_length').off('click').on('input', onOverrideResponseLengthInput);905 $('#memory_override_response_length').off('click').on('input', onOverrideResponseLengthInput);
896 $('#memory_max_messages_per_request').off('click').on('input', onMaxMessagesPerRequestInput);906 $('#memory_max_messages_per_request').off('click').on('input', onMaxMessagesPerRequestInput);
907 $('#memory_include_wi_scan').off('input').on('input', onMemoryIncludeWIScanInput);
897 $('#summarySettingsBlockToggle').off('click').on('click', function () {908 $('#summarySettingsBlockToggle').off('click').on('click', function () {
898 console.log('saw settings button click');909 console.log('saw settings button click');
899 $('#summarySettingsBlock').slideToggle(200, 'swing'); //toggleClass("hidden");910 $('#summarySettingsBlock').slideToggle(200, 'swing'); //toggleClass("hidden");
public/scripts/extensions/memory/settings.html+9 -0
@@ -109,8 +109,17 @@
109 <textarea id="memory_template" class="text_pole textarea_compact" rows="2" data-i18n="[placeholder]ext_sum_memory_template_placeholder" placeholder="&lcub;&lcub;summary&rcub;&rcub; will resolve to the current summary contents."></textarea>109 <textarea id="memory_template" class="text_pole textarea_compact" rows="2" data-i18n="[placeholder]ext_sum_memory_template_placeholder" placeholder="&lcub;&lcub;summary&rcub;&rcub; will resolve to the current summary contents."></textarea>
110 </div>110 </div>
111 <label for="memory_position" data-i18n="ext_sum_injection_position">Injection Position</label>111 <label for="memory_position" data-i18n="ext_sum_injection_position">Injection Position</label>
112 <label class="checkbox_label" for="memory_include_wi_scan" data-i18n="[title]ext_sum_include_wi_scan_desc" title="Include the latest summary in the WI scan.">
113 <input id="memory_include_wi_scan" type="checkbox" />
114 <span data-i18n="ext_sum_include_wi_scan">Include in World Info Scanning</span>
115 </label>
112 <div class="radio_group">116 <div class="radio_group">
113 <label>117 <label>
118 <input type="radio" name="memory_position" value="-1" />
119 <span data-i18n="None (not injected)">None (not injected)</span>
120 <i class="fa-solid fa-info-circle" title="The summary will not be injected into the prompt. You can still access it via the &lcub;&lcub;summary&rcub;&rcub; macro." data-i18n="[title]ext_sum_injection_position_none"></i>
121 </label>
122 <label>
114 <input type="radio" name="memory_position" value="2" />123 <input type="radio" name="memory_position" value="2" />
115 <span data-i18n="Before Main Prompt / Story String">Before Main Prompt / Story String</span>124 <span data-i18n="Before Main Prompt / Story String">Before Main Prompt / Story String</span>
116 </label>125 </label>
public/scripts/power-user.js+30 -7
@@ -2968,7 +2968,13 @@ function setAvgBG() {
2968 return '';2968 return '';
2969}2969}
29702970
2971async function setThemeCallback(_, text) {2971async function setThemeCallback(_, themeName) {
2972 if (!themeName) {
2973 // allow reporting of the theme name if called without args
2974 // for use in ST Scripts via pipe
2975 return power_user.theme;
2976 }
2977
2972 // @ts-ignore2978 // @ts-ignore
2973 const fuse = new Fuse(themes, {2979 const fuse = new Fuse(themes, {
2974 keys: [2980 keys: [
@@ -2976,12 +2982,12 @@ async function setThemeCallback(_, text) {
2976 ],2982 ],
2977 });2983 });
29782984
2979 const results = fuse.search(text);2985 const results = fuse.search(themeName);
2980 console.debug('Theme fuzzy search results for ' + text, results);2986 console.debug('Theme fuzzy search results for ' + themeName, results);
2981 const theme = results[0]?.item;2987 const theme = results[0]?.item;
29822988
2983 if (!theme) {2989 if (!theme) {
2984 toastr.warning(`Could not find theme with name: ${text}`);2990 toastr.warning(`Could not find theme with name: ${themeName}`);
2985 return;2991 return;
2986 }2992 }
29872993
@@ -4056,13 +4062,30 @@ $(document).ready(() => {
4056 callback: setThemeCallback,4062 callback: setThemeCallback,
4057 unnamedArgumentList: [4063 unnamedArgumentList: [
4058 SlashCommandArgument.fromProps({4064 SlashCommandArgument.fromProps({
4059 description: 'name',4065 description: 'theme name',
4060 typeList: [ARGUMENT_TYPE.STRING],4066 typeList: [ARGUMENT_TYPE.STRING],
4061 isRequired: true,
4062 enumProvider: () => themes.map(theme => new SlashCommandEnumValue(theme.name)),4067 enumProvider: () => themes.map(theme => new SlashCommandEnumValue(theme.name)),
4063 }),4068 }),
4064 ],4069 ],
4065 helpString: 'sets a UI theme by name',4070 helpString: `
4071 <div>
4072 Sets a UI theme by name.
4073 </div>
4074 <div>
4075 If no theme name is is provided, this will return the currently active theme.
4076 </div>
4077 <div>
4078 <strong>Example:</strong>
4079 <ul>
4080 <li>
4081 <pre><code>/theme Cappuccino</code></pre>
4082 </li>
4083 <li>
4084 <pre><code>/theme</code></pre>
4085 </li>
4086 </ul>
4087 </div>
4088 `,
4066 }));4089 }));
4067 SlashCommandParser.addCommandObject(SlashCommand.fromProps({4090 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
4068 name: 'movingui',4091 name: 'movingui',
public/scripts/slash-commands.js+16 -5
@@ -139,9 +139,8 @@ export function initDefaultSlashCommands() {
139 returns: 'the current background',139 returns: 'the current background',
140 unnamedArgumentList: [140 unnamedArgumentList: [
141 SlashCommandArgument.fromProps({141 SlashCommandArgument.fromProps({
142 description: 'filename',142 description: 'background filename',
143 typeList: [ARGUMENT_TYPE.STRING],143 typeList: [ARGUMENT_TYPE.STRING],
144 isRequired: true,
145 enumProvider: () => [...document.querySelectorAll('.bg_example')]144 enumProvider: () => [...document.querySelectorAll('.bg_example')]
146 .map(it => new SlashCommandEnumValue(it.getAttribute('bgfile')))145 .map(it => new SlashCommandEnumValue(it.getAttribute('bgfile')))
147 .filter(it => it.value?.length),146 .filter(it => it.value?.length),
@@ -152,11 +151,17 @@ export function initDefaultSlashCommands() {
152 Sets a background according to the provided filename. Partial names allowed.151 Sets a background according to the provided filename. Partial names allowed.
153 </div>152 </div>
154 <div>153 <div>
154 If no background is provided, this will return the currently selected background.
155 </div>
156 <div>
155 <strong>Example:</strong>157 <strong>Example:</strong>
156 <ul>158 <ul>
157 <li>159 <li>
158 <pre><code>/bg beach.jpg</code></pre>160 <pre><code>/bg beach.jpg</code></pre>
159 </li>161 </li>
162 <li>
163 <pre><code>/bg</code></pre>
164 </li>
160 </ul>165 </ul>
161 </div>166 </div>
162 `,167 `,
@@ -1356,7 +1361,7 @@ export function initDefaultSlashCommands() {
1356 enumProvider: commonEnumProviders.injects,1361 enumProvider: commonEnumProviders.injects,
1357 }),1362 }),
1358 new SlashCommandNamedArgument(1363 new SlashCommandNamedArgument(
1359 'position', 'injection position', [ARGUMENT_TYPE.STRING], false, false, 'after', ['before', 'after', 'chat'],1364 'position', 'injection position', [ARGUMENT_TYPE.STRING], false, false, 'after', ['before', 'after', 'chat', 'none'],
1360 ),1365 ),
1361 new SlashCommandNamedArgument(1366 new SlashCommandNamedArgument(
1362 'depth', 'injection depth', [ARGUMENT_TYPE.NUMBER], false, false, '4',1367 'depth', 'injection depth', [ARGUMENT_TYPE.NUMBER], false, false, '4',
@@ -1384,7 +1389,7 @@ export function initDefaultSlashCommands() {
1384 'text', [ARGUMENT_TYPE.STRING], false,1389 'text', [ARGUMENT_TYPE.STRING], false,
1385 ),1390 ),
1386 ],1391 ],
1387 helpString: 'Injects a text into the LLM prompt for the current chat. Requires a unique injection ID. Positions: "before" main prompt, "after" main prompt, in-"chat" (default: after). Depth: injection depth for the prompt (default: 4). Role: role for in-chat injections (default: system). Scan: include injection content into World Info scans (default: false).',1392 helpString: 'Injects a text into the LLM prompt for the current chat. Requires a unique injection ID. Positions: "before" main prompt, "after" main prompt, in-"chat", hidden with "none" (default: after). Depth: injection depth for the prompt (default: 4). Role: role for in-chat injections (default: system). Scan: include injection content into World Info scans (default: false). Hidden injects in "none" position are not inserted into the prompt but can be used for triggering WI entries.',
1388 }));1393 }));
1389 SlashCommandParser.addCommandObject(SlashCommand.fromProps({1394 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
1390 name: 'listinjects',1395 name: 'listinjects',
@@ -1486,6 +1491,7 @@ function injectCallback(args, value) {
1486 'before': extension_prompt_types.BEFORE_PROMPT,1491 'before': extension_prompt_types.BEFORE_PROMPT,
1487 'after': extension_prompt_types.IN_PROMPT,1492 'after': extension_prompt_types.IN_PROMPT,
1488 'chat': extension_prompt_types.IN_CHAT,1493 'chat': extension_prompt_types.IN_CHAT,
1494 'none': extension_prompt_types.NONE,
1489 };1495 };
1490 const roles = {1496 const roles = {
1491 'system': extension_prompt_roles.SYSTEM,1497 'system': extension_prompt_roles.SYSTEM,
@@ -2846,7 +2852,6 @@ export async function sendMessageAs(args, text) {
28462852
2847 if (args.name) {2853 if (args.name) {
2848 name = args.name.trim();2854 name = args.name.trim();
2849 mesText = text.trim();
28502855
2851 if (!name && !text) {2856 if (!name && !text) {
2852 toastr.warning('You must specify a name and text to send as');2857 toastr.warning('You must specify a name and text to send as');
@@ -2859,8 +2864,14 @@ export async function sendMessageAs(args, text) {
2859 localStorage.setItem(namelessWarningKey, 'true');2864 localStorage.setItem(namelessWarningKey, 'true');
2860 }2865 }
2861 name = name2;2866 name = name2;
2867 if (!text) {
2868 toastr.warning('You must specify text to send as');
2869 return '';
2870 }
2862 }2871 }
28632872
2873 mesText = text.trim();
2874
2864 // Requires a regex check after the slash command is pushed to output2875 // Requires a regex check after the slash command is pushed to output
2865 mesText = getRegexedString(mesText, regex_placement.SLASH_COMMAND, { characterOverride: name });2876 mesText = getRegexedString(mesText, regex_placement.SLASH_COMMAND, { characterOverride: name });
28662877
public/scripts/tags.js+0 -19
@@ -1367,27 +1367,8 @@ function makeTagListDraggable(tagContainer) {
1367 const id = $(tagElement).attr('id');1367 const id = $(tagElement).attr('id');
1368 const tag = tags.find(x => x.id === id);1368 const tag = tags.find(x => x.id === id);
13691369
1370 // Fix the defined colors, because if there is no color set, they seem to get automatically set to black
1371 // based on the color picker after drag&drop, even if there was no color chosen. We just set them back.
1372 const color = $(tagElement).find('.tagColorPickerHolder .tag-color').attr('color');
1373 const color2 = $(tagElement).find('.tagColorPicker2Holder .tag-color2').attr('color');
1374 if (color === '' || color === undefined) {
1375 tag.color = '';
1376 fixColor('background-color', tag.color);
1377 }
1378 if (color2 === '' || color2 === undefined) {
1379 tag.color2 = '';
1380 fixColor('color', tag.color2);
1381 }
1382
1383 // Update the sort order1370 // Update the sort order
1384 tag.sort_order = i;1371 tag.sort_order = i;
1385
1386 function fixColor(property, color) {
1387 $(tagElement).find('.tag_view_name').css(property, color);
1388 $(`.tag[id="${id}"]`).css(property, color);
1389 $(`.bogus_folder_select[tagid="${id}"] .avatar`).css(property, color);
1390 }
1391 });1372 });
13921373
1393 // If tags were dragged manually, we have to disable auto sorting1374 // If tags were dragged manually, we have to disable auto sorting
public/scripts/templates/tabbyDownloader.html+2 -2
@@ -1,6 +1,6 @@
1<div id="tabby_downloader_popup">1<div id="tabby_downloader_popup">
2 <div>2 <div>
3 <h3><strong data-i18n="">Download Model</strong>3 <h3><strong data-i18n="Download Model">Download Model</strong>
4 <a href="https://github.com/theroyallab/async-hf-downloader" class="notes-link" target="_blank">4 <a href="https://github.com/theroyallab/async-hf-downloader" class="notes-link" target="_blank">
5 <span class="note-link-span">?</span>5 <span class="note-link-span">?</span>
6 </a>6 </a>
@@ -58,4 +58,4 @@
58 <textarea class="text_pole textarea_compact" name="tabby_download_exclude" placeholder="Ex. *.txt"></textarea>58 <textarea class="text_pole textarea_compact" name="tabby_download_exclude" placeholder="Ex. *.txt"></textarea>
59 </div>59 </div>
60 </div>60 </div>
61</div>
61 \ No newline at end of file \ No newline at end of file
61</div>
public/scripts/templates/welcome.html+1 -1
@@ -31,7 +31,7 @@
31<h3 data-i18n="Confused or lost?">Confused or lost?</h3>31<h3 data-i18n="Confused or lost?">Confused or lost?</h3>
32<ul>32<ul>
33 <li>33 <li>
34 <span class="note-link-span"><a class="fa-solid fa-circle-question" target="_blank" href="https://docs.sillytavern.app/" data-i18n=""></a></span> - <span data-i18n="click these icons!">click these icons!</span>34 <span class="note-link-span"><a class="fa-solid fa-circle-question" target="_blank" href="https://docs.sillytavern.app/"></a></span> - <span data-i18n="click these icons!">click these icons!</span>
35 </li>35 </li>
36 <li>36 <li>
37 <span data-i18n="Enter">Enter </span><code>/?</code><span data-i18n="in the chat bar"> in the chat bar</span>37 <span data-i18n="Enter">Enter </span><code>/?</code><span data-i18n="in the chat bar"> in the chat bar</span>