Merge branch 'staging' into group-join-examples

d7328af4c8d4541e792e83169c9f24df15c34452

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

25 files changed, +426 -346Showing whitespace changes
package-lock.json+7 -0
@@ -63,6 +63,7 @@
63 "showdown": "^2.1.0",63 "showdown": "^2.1.0",
64 "sillytavern-transformers": "2.14.6",64 "sillytavern-transformers": "2.14.6",
65 "simple-git": "^3.19.1",65 "simple-git": "^3.19.1",
66 "slidetoggle": "^4.0.0",
66 "tiktoken": "^1.0.16",67 "tiktoken": "^1.0.16",
67 "vectra": "^0.2.2",68 "vectra": "^0.2.2",
68 "wavefile": "^11.0.0",69 "wavefile": "^11.0.0",
@@ -6531,6 +6532,12 @@
6531 "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==",6532 "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==",
6532 "license": "MIT"6533 "license": "MIT"
6533 },6534 },
6535 "node_modules/slidetoggle": {
6536 "version": "4.0.0",
6537 "resolved": "https://registry.npmjs.org/slidetoggle/-/slidetoggle-4.0.0.tgz",
6538 "integrity": "sha512-6qvrOS1dnDFEr41UEEFFRQE8nswaAFIYZAHer6dVlznRIjHyCISjNJoxIn5U5QlAbZfBBxTELQk4jS7miHto1A==",
6539 "license": "MIT"
6540 },
6534 "node_modules/smart-buffer": {6541 "node_modules/smart-buffer": {
6535 "version": "4.2.0",6542 "version": "4.2.0",
6536 "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",6543 "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
package.json+1 -0
@@ -53,6 +53,7 @@
53 "showdown": "^2.1.0",53 "showdown": "^2.1.0",
54 "sillytavern-transformers": "2.14.6",54 "sillytavern-transformers": "2.14.6",
55 "simple-git": "^3.19.1",55 "simple-git": "^3.19.1",
56 "slidetoggle": "^4.0.0",
56 "tiktoken": "^1.0.16",57 "tiktoken": "^1.0.16",
57 "vectra": "^0.2.2",58 "vectra": "^0.2.2",
58 "wavefile": "^11.0.0",59 "wavefile": "^11.0.0",
public/img/generic.svg+15 -0
@@ -0,0 +1,15 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<svg
3 width="616.86328"
4 height="616.86328"
5 viewBox="0 0 77.10791 77.10791"
6 version="1.1"
7 id="svg4"
8 xmlns="http://www.w3.org/2000/svg"
9 xmlns:svg="http://www.w3.org/2000/svg">
10 <defs
11 id="defs4" />
12 <path
13 id="circle1"
14 d="M 38.553955,0 A 38.554,38.554 0 0 0 0,38.553955 38.554,38.554 0 0 0 38.553955,77.107911 38.554,38.554 0 0 0 77.107911,38.553955 38.554,38.554 0 0 0 38.553955,0 Z m -3.125976,13.545898 h 6.251953 v 19.593751 l 16.968751,-9.796875 3.125974,5.414306 -16.968506,9.796875 16.968506,9.796877 -3.125974,5.414305 -16.968751,-9.796874 V 63.56201 H 35.427979 V 43.968263 l -16.968506,9.796874 -3.125977,-5.414305 16.96875,-9.796877 -16.96875,-9.796875 3.125977,-5.414306 16.968506,9.796875 z" />
15</svg>
public/index.html+16 -18
@@ -1736,6 +1736,7 @@
1736 <div data-name="tfs_z" draggable="true"><span>Tail Free Sampling</span><small></small></div>1736 <div data-name="tfs_z" draggable="true"><span>Tail Free Sampling</span><small></small></div>
1737 <div data-name="min_p" draggable="true"><span>Min P</span><small></small></div>1737 <div data-name="min_p" draggable="true"><span>Min P</span><small></small></div>
1738 <div data-name="xtc" draggable="true"><span>Exclude Top Choices</span><small></small></div>1738 <div data-name="xtc" draggable="true"><span>Exclude Top Choices</span><small></small></div>
1739 <div data-name="dry" draggable="true"><span>DRY</span><small></small></div>
1739 </div>1740 </div>
1740 <div id="llamacpp_samplers_default_order" class="menu_button menu_button_icon">1741 <div id="llamacpp_samplers_default_order" class="menu_button menu_button_icon">
1741 <span data-i18n="Load default order">Load default order</span>1742 <span data-i18n="Load default order">Load default order</span>
@@ -2616,7 +2617,7 @@
2616 </div>2617 </div>
2617 </div>2618 </div>
2618 <div class="flex-container flexFlowColumn marginTopBot5">2619 <div class="flex-container flexFlowColumn marginTopBot5">
2619 <label data-tg-type="ooba" class="checkbox_label" for="bypass_status_check_textgenerationwebui">2620 <label data-tg-type="ooba, generic" class="checkbox_label" for="bypass_status_check_textgenerationwebui">
2620 <input type="checkbox" id="bypass_status_check_textgenerationwebui" />2621 <input type="checkbox" id="bypass_status_check_textgenerationwebui" />
2621 <span data-i18n="Bypass status check">Bypass status check</span>2622 <span data-i18n="Bypass status check">Bypass status check</span>
2622 </label>2623 </label>
@@ -3025,34 +3026,30 @@
3025 <optgroup label="Primary">3026 <optgroup label="Primary">
3026 <option value="gemini-1.5-pro">Gemini 1.5 Pro</option>3027 <option value="gemini-1.5-pro">Gemini 1.5 Pro</option>
3027 <option value="gemini-1.5-flash">Gemini 1.5 Flash</option>3028 <option value="gemini-1.5-flash">Gemini 1.5 Flash</option>
3028 <option value="gemini-1.0-pro">Gemini 1.0 Pro</option>3029 <option value="gemini-1.0-pro">Gemini 1.0 Pro (Deprecated)</option>
3029 <option value="gemini-pro">Gemini Pro (1.0)</option>3030 <option value="gemini-pro">Gemini Pro (1.0) (Deprecated)</option>
3030 <option value="gemini-pro-vision">Gemini Pro Vision (1.0)</option>
3031 <option value="gemini-ultra">Gemini Ultra (1.0)</option>3031 <option value="gemini-ultra">Gemini Ultra (1.0)</option>
3032 <option value="gemini-1.0-ultra-latest">Gemini 1.0 Ultra</option>3032 <option value="gemini-1.0-ultra-latest">Gemini 1.0 Ultra</option>
3033 <option value="text-bison-001">PaLM 2 (Legacy)</option>
3034 <option value="chat-bison-001">PaLM 2 Chat (Legacy)</option>
3035 </optgroup>3033 </optgroup>
3036 <optgroup label="Subversions">3034 <optgroup label="Subversions">
3037 <option value="gemini-2.0-flash-exp">Gemini 2.0 Flash Experiment</option>3035 <option value="gemini-2.0-flash-exp">Gemini 2.0 Flash Experimental</option>
3038 <option value="gemini-exp-1114">Gemini Experimental 2024-11-14</option>3036 <option value="gemini-exp-1114">Gemini Experimental 2024-11-14</option>
3039 <option value="gemini-exp-1121">Gemini Experimental 2024-11-21</option>3037 <option value="gemini-exp-1121">Gemini Experimental 2024-11-21</option>
3040 <option value="gemini-exp-1206">Gemini Experimental 2024-12-06</option>3038 <option value="gemini-exp-1206">Gemini Experimental 2024-12-06</option>
3041 <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experiment 2024-08-01</option>3039 <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experimental 2024-08-01</option>
3042 <option value="gemini-1.5-pro-exp-0827">Gemini 1.5 Pro Experiment 2024-08-27</option>3040 <option value="gemini-1.5-pro-exp-0827">Gemini 1.5 Pro Experimental 2024-08-27</option>
3043 <option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option>3041 <option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option>
3044 <option value="gemini-1.5-pro-001">Gemini 1.5 Pro [001]</option>3042 <option value="gemini-1.5-pro-001">Gemini 1.5 Pro [001]</option>
3045 <option value="gemini-1.5-pro-002">Gemini 1.5 Pro [002]</option>3043 <option value="gemini-1.5-pro-002">Gemini 1.5 Pro [002]</option>
3046 <option value="gemini-1.5-flash-8b">Gemini 1.5 Flash 8B</option>3044 <option value="gemini-1.5-flash-8b">Gemini 1.5 Flash 8B</option>
3047 <option value="gemini-1.5-flash-exp-0827">Gemini 1.5 Flash Experiment 2024-08-27</option>3045 <option value="gemini-1.5-flash-exp-0827">Gemini 1.5 Flash Experimental 2024-08-27</option>
3048 <option value="gemini-1.5-flash-8b-exp-0827">Gemini 1.5 Flash 8B Experiment 2024-08-27</option>3046 <option value="gemini-1.5-flash-8b-exp-0827">Gemini 1.5 Flash 8B Experimental 2024-08-27</option>
3049 <option value="gemini-1.5-flash-8b-exp-0924">Gemini 1.5 Flash 8B Experiment 2024-09-24</option>3047 <option value="gemini-1.5-flash-8b-exp-0924">Gemini 1.5 Flash 8B Experimental 2024-09-24</option>
3050 <option value="gemini-1.5-flash-latest">Gemini 1.5 Flash [latest]</option>3048 <option value="gemini-1.5-flash-latest">Gemini 1.5 Flash [latest]</option>
3051 <option value="gemini-1.5-flash-001">Gemini 1.5 Flash [001]</option>3049 <option value="gemini-1.5-flash-001">Gemini 1.5 Flash [001]</option>
3052 <option value="gemini-1.5-flash-002">Gemini 1.5 Flash [002]</option>3050 <option value="gemini-1.5-flash-002">Gemini 1.5 Flash [002]</option>
3053 <option value="gemini-1.0-pro-latest">Gemini 1.0 Pro [latest]</option>3051 <option value="gemini-1.0-pro-latest">Gemini 1.0 Pro [latest] (Deprecated)</option>
3054 <option value="gemini-1.0-pro-001">Gemini 1.0 Pro (Tuning) [001]</option>3052 <option value="gemini-1.0-pro-001">Gemini 1.0 Pro (Tuning) [001] (Deprecated)</option>
3055 <option value="gemini-1.0-pro-vision-latest">Gemini 1.0 Pro Vision [latest]</option>
3056 </optgroup>3053 </optgroup>
3057 </select>3054 </select>
3058 </div>3055 </div>
@@ -3220,16 +3217,17 @@
3220 <h4 data-i18n="Cohere Model">Cohere Model</h4>3217 <h4 data-i18n="Cohere Model">Cohere Model</h4>
3221 <select id="model_cohere_select">3218 <select id="model_cohere_select">
3222 <optgroup label="Stable">3219 <optgroup label="Stable">
3223 <option value="c4ai-aya-expanse-32b">c4ai-aya-expanse-32b</option>
3224 <option value="c4ai-aya-expanse-8b">c4ai-aya-expanse-8b</option>
3225 <option value="c4ai-aya-23-35b">c4ai-aya-23-35b</option>
3226 <option value="c4ai-aya-23-8b">c4ai-aya-23-8b</option>3220 <option value="c4ai-aya-23-8b">c4ai-aya-23-8b</option>
3221 <option value="c4ai-aya-23">c4ai-aya-23</option>
3222 <option value="c4ai-aya-expanse-8b">c4ai-aya-expanse-8b</option>
3223 <option value="c4ai-aya-expanse-32b">c4ai-aya-expanse-32b</option>
3227 <option value="command-light">command-light</option>3224 <option value="command-light">command-light</option>
3228 <option value="command">command</option>3225 <option value="command">command</option>
3229 <option value="command-r">command-r</option>3226 <option value="command-r">command-r</option>
3230 <option value="command-r-plus">command-r-plus</option>3227 <option value="command-r-plus">command-r-plus</option>
3231 <option value="command-r-08-2024">command-r-08-2024</option>3228 <option value="command-r-08-2024">command-r-08-2024</option>
3232 <option value="command-r-plus-08-2024">command-r-plus-08-2024</option>3229 <option value="command-r-plus-08-2024">command-r-plus-08-2024</option>
3230 <option value="command-r7b-12-2024">command-r7b-12-2024</option>
3233 </optgroup>3231 </optgroup>
3234 <optgroup label="Nightly">3232 <optgroup label="Nightly">
3235 <option value="command-light-nightly">command-light-nightly</option>3233 <option value="command-light-nightly">command-light-nightly</option>
public/lib.js+3 -0
@@ -19,6 +19,7 @@ import seedrandom from 'seedrandom';
19import * as Popper from '@popperjs/core';19import * as Popper from '@popperjs/core';
20import droll from 'droll';20import droll from 'droll';
21import morphdom from 'morphdom';21import morphdom from 'morphdom';
22import { toggle as slideToggle } from 'slidetoggle';
2223
23/**24/**
24 * Expose the libraries to the 'window' object.25 * Expose the libraries to the 'window' object.
@@ -94,6 +95,7 @@ export default {
94 Popper,95 Popper,
95 droll,96 droll,
96 morphdom,97 morphdom,
98 slideToggle,
97};99};
98100
99export {101export {
@@ -115,4 +117,5 @@ export {
115 Popper,117 Popper,
116 droll,118 droll,
117 morphdom,119 morphdom,
120 slideToggle,
118};121};
public/locales/ja-jp.json+6 -1
@@ -1274,6 +1274,8 @@
1274 "sd_Raw_Last_Message": "生の最後のメッセージ",1274 "sd_Raw_Last_Message": "生の最後のメッセージ",
1275 "sd_Background": "背景",1275 "sd_Background": "背景",
1276 "Image Generation": "画像生成",1276 "Image Generation": "画像生成",
1277 "Stop Image Generation": "画像生成を停止",
1278 "Generate Caption": "画像説明を生成",
1277 "sd_refine_mode": "プロンプトを生成 API に送信する前に手動で編集できるようにする",1279 "sd_refine_mode": "プロンプトを生成 API に送信する前に手動で編集できるようにする",
1278 "sd_refine_mode_txt": "生成前にプロンプ​​トを編集する",1280 "sd_refine_mode_txt": "生成前にプロンプ​​トを編集する",
1279 "sd_interactive_mode": "「猫の写真を送ってください」のようなメッセージを送信するときに、画像を自動的に生成します。",1281 "sd_interactive_mode": "「猫の写真を送ってください」のようなメッセージを送信するときに、画像を自動的に生成します。",
@@ -1439,5 +1441,8 @@
1439 "Still have questions?": "まだ質問がありますか?",1441 "Still have questions?": "まだ質問がありますか?",
1440 "Join the SillyTavern Discord": "SillyTavernのDiscordに参加",1442 "Join the SillyTavern Discord": "SillyTavernのDiscordに参加",
1441 "Post a GitHub issue": "GitHubの問題を投稿",1443 "Post a GitHub issue": "GitHubの問題を投稿",
1442 "Contact the developers": "開発者に連絡"1444 "Contact the developers": "開発者に連絡",
1445 "Stop Inspecting": "検査を停止",
1446 "Inspect Prompts": "プロンプトを検査",
1447 "Toggle prompt inspection": "プロンプト検査の切り替え"
1443}1448}
public/locales/zh-cn.json+6 -1
@@ -1241,6 +1241,7 @@
1241 "Enter web URLs to scrape (one per line):": "输入要抓取的网址(每行一个):",1241 "Enter web URLs to scrape (one per line):": "输入要抓取的网址(每行一个):",
1242 "Enter a video URL to download its transcript.": "输入视频 URL 或 ID 即可下载其文本。",1242 "Enter a video URL to download its transcript.": "输入视频 URL 或 ID 即可下载其文本。",
1243 "Image Captioning": "图像描述",1243 "Image Captioning": "图像描述",
1244 "Generate Caption": "生成图片说明",
1244 "Source": "来源",1245 "Source": "来源",
1245 "Local": "本地",1246 "Local": "本地",
1246 "Multimodal (OpenAI / Anthropic / llama / Google)": "多模式(OpenAI / Anthropic / llama / Google)",1247 "Multimodal (OpenAI / Anthropic / llama / Google)": "多模式(OpenAI / Anthropic / llama / Google)",
@@ -1430,6 +1431,7 @@
1430 "sd_Raw_Last_Message": "原始最后一条消息",1431 "sd_Raw_Last_Message": "原始最后一条消息",
1431 "sd_Background": "背景",1432 "sd_Background": "背景",
1432 "Image Generation": "图像生成",1433 "Image Generation": "图像生成",
1434 "Stop Image Generation": "中止图像生成",
1433 "sd_refine_mode": "允许在将提示词发送到生成 API 之前手动编辑提示词",1435 "sd_refine_mode": "允许在将提示词发送到生成 API 之前手动编辑提示词",
1434 "sd_refine_mode_txt": "生成之前编辑提示词",1436 "sd_refine_mode_txt": "生成之前编辑提示词",
1435 "sd_interactive_mode": "发送消息时自动生成图像,例如“给我发一张猫的照片”。",1437 "sd_interactive_mode": "发送消息时自动生成图像,例如“给我发一张猫的照片”。",
@@ -1861,5 +1863,8 @@
1861 "Still have questions?": "仍有疑问?",1863 "Still have questions?": "仍有疑问?",
1862 "Join the SillyTavern Discord": "加入SillyTavern Discord",1864 "Join the SillyTavern Discord": "加入SillyTavern Discord",
1863 "Post a GitHub issue": "发布GitHub问题",1865 "Post a GitHub issue": "发布GitHub问题",
1864 "Contact the developers": "联系开发人员"1866 "Contact the developers": "联系开发人员",
1867 "Stop Inspecting": "停止检查",
1868 "Inspect Prompts": "检查提示词",
1869 "Toggle prompt inspection": "切换提示词检查"
1865}1870}
public/locales/zh-tw.json+127 -122
@@ -65,20 +65,20 @@
65 "Min P": "Min P",65 "Min P": "Min P",
66 "Top A": "Top A",66 "Top A": "Top A",
67 "Quick Prompts Edit": "快速提示詞編輯",67 "Quick Prompts Edit": "快速提示詞編輯",
68 "Main": "主要",68 "Main": "主要提示詞",
69 "NSFW": "NSFW",69 "NSFW": "NSFW",
70 "Jailbreak": "越獄",70 "Jailbreak": "越獄",
71 "Utility Prompts": "實用提示詞",71 "Utility Prompts": "實用提示詞",
72 "Impersonation prompt": "AI 扮演提示詞",72 "Impersonation prompt": "AI 扮演提示詞",
73 "Restore default prompt": "還原預設提示詞",73 "Restore default prompt": "還原預設提示詞",
74 "Prompt that is used for Impersonation function": "用於 AI 模仿功能的提示詞",74 "Prompt that is used for Impersonation function": "用於 AI 模仿功能的提示詞",
75 "World Info Format Template": "世界資訊格式範本",75 "World Info Format Template": "世界資訊格式",
76 "Restore default format": "還原預設格式",76 "Restore default format": "還原預設格式",
77 "Wraps activated World Info entries before inserting into the prompt.": "在插入提示詞前包裝已啟用的世界資訊條目。",77 "Wraps activated World Info entries before inserting into the prompt.": "在插入提示詞前包裝已啟用的世界資訊條目。",
78 "scenario_format_template_part_1": "使用",78 "scenario_format_template_part_1": "使用",
79 "scenario_format_template_part_2": "來標示要插入內容的位置。",79 "scenario_format_template_part_2": "來標示要插入內容的位置。",
80 "Scenario Format Template": "情境格式範本",80 "Scenario Format Template": "情境格式",
81 "Personality Format Template": "個性格式範本",81 "Personality Format Template": "個性格式",
82 "Group Nudge Prompt Template": "群組推動提示詞範本",82 "Group Nudge Prompt Template": "群組推動提示詞範本",
83 "Sent at the end of the group chat history to force reply from a specific character.": "在群組聊天歷史結束時發送以強制特定角色回覆",83 "Sent at the end of the group chat history to force reply from a specific character.": "在群組聊天歷史結束時發送以強制特定角色回覆",
84 "New Chat": "新聊天",84 "New Chat": "新聊天",
@@ -412,7 +412,7 @@
412 "Chat Start": "聊天開始符號",412 "Chat Start": "聊天開始符號",
413 "Add Chat Start and Example Separator to a list of stopping strings.": "將聊天開始和範例分隔符號加入終止字串中。",413 "Add Chat Start and Example Separator to a list of stopping strings.": "將聊天開始和範例分隔符號加入終止字串中。",
414 "Use as Stop Strings": "用作停止字串",414 "Use as Stop Strings": "用作停止字串",
415 "context_allow_jailbreak": "如果在角色卡中定義了越獄,且啟用了「偏好角色卡越獄」,則會在提示詞的結尾加入越獄內容。\n這不建議用於文字完成模型,因為可能導致不良的輸出結果。",415 "context_allow_jailbreak": "如果在角色卡中定義了越獄,且啟用了「角色卡越獄優先」,則會在提示詞的結尾加入越獄內容。\n這不建議用於文字完成模型,因為可能導致不良的輸出結果。",
416 "Allow Jailbreak": "允許越獄",416 "Allow Jailbreak": "允許越獄",
417 "Context Order": "上下文順序",417 "Context Order": "上下文順序",
418 "Summary": "摘要",418 "Summary": "摘要",
@@ -631,9 +631,9 @@
631 "Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring": "使用模糊配對,並通過所有資料欄位在列表中搜尋角色,而不僅僅是通過名稱子字串。",631 "Use fuzzy matching, and search characters in the list by all data fields, not just by a name substring": "使用模糊配對,並通過所有資料欄位在列表中搜尋角色,而不僅僅是通過名稱子字串。",
632 "Advanced Character Search": "進階角色搜尋",632 "Advanced Character Search": "進階角色搜尋",
633 "If checked and the character card contains a prompt override (System Prompt), use that instead": "如果選中並且角色卡包含提示詞覆寫(系統提示詞),則使用該提示詞。",633 "If checked and the character card contains a prompt override (System Prompt), use that instead": "如果選中並且角色卡包含提示詞覆寫(系統提示詞),則使用該提示詞。",
634 "Prefer Character Card Prompt": "偏好角色卡主要提示詞",634 "Prefer Character Card Prompt": "角色卡主要提示詞優先",
635 "If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "如果選中並且角色卡包含越獄覆寫(聊天歷史後指示),則使用該提示詞。",635 "If checked and the character card contains a jailbreak override (Post History Instruction), use that instead": "如果選中並且角色卡包含越獄覆寫(聊天歷史後指示),則使用該提示詞。",
636 "Prefer Character Card Jailbreak": "偏好角色卡越獄",636 "Prefer Character Card Jailbreak": "角色卡越獄優先",
637 "Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "避免裁剪和調整匯入的角色圖像大小。未勾選時將會裁剪/調整大小到 512x768。",637 "Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "避免裁剪和調整匯入的角色圖像大小。未勾選時將會裁剪/調整大小到 512x768。",
638 "Never resize avatars": "永不調整頭像大小",638 "Never resize avatars": "永不調整頭像大小",
639 "Show actual file names on the disk, in the characters list display only": "僅在角色列表顯示實際檔案名稱。",639 "Show actual file names on the disk, in the characters list display only": "僅在角色列表顯示實際檔案名稱。",
@@ -1018,7 +1018,7 @@
1018 "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "注入深度。0 = 在最後一則訊息之後,1 = 在最後一則訊息之前,以此類推。",1018 "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "注入深度。0 = 在最後一則訊息之後,1 = 在最後一則訊息之前,以此類推。",
1019 "Prompt": "提示詞",1019 "Prompt": "提示詞",
1020 "The prompt to be sent.": "要發送的提示詞。",1020 "The prompt to be sent.": "要發送的提示詞。",
1021 "This prompt cannot be overridden by character cards, even if overrides are preferred.": "即使啟用偏好覆寫,此提示詞也不能被角色卡片覆寫。",1021 "This prompt cannot be overridden by character cards, even if overrides are preferred.": "即使啟用優先覆寫,此提示詞也不能被角色卡片覆寫。",
1022 "prompt_manager_forbid_overrides": "禁止覆寫",1022 "prompt_manager_forbid_overrides": "禁止覆寫",
1023 "reset": "重設",1023 "reset": "重設",
1024 "save": "節省",1024 "save": "節省",
@@ -1026,6 +1026,7 @@
1026 "Message Actions": "訊息動作",1026 "Message Actions": "訊息動作",
1027 "Translate message": "翻譯訊息",1027 "Translate message": "翻譯訊息",
1028 "Generate Image": "生成圖片",1028 "Generate Image": "生成圖片",
1029 "Stop Image Generation": "終止圖片生成",
1029 "Narrate": "敘述",1030 "Narrate": "敘述",
1030 "Exclude message from prompts": "從提示詞中排除訊息",1031 "Exclude message from prompts": "從提示詞中排除訊息",
1031 "Include message in prompts": "在提示詞中包含訊息",1032 "Include message in prompts": "在提示詞中包含訊息",
@@ -1343,12 +1344,12 @@
1343 "sd_prompt_prefix_placeholder": "使用 {prompt} 指定生成的提示詞將被插入的位置。",1344 "sd_prompt_prefix_placeholder": "使用 {prompt} 指定生成的提示詞將被插入的位置。",
1344 "Negative common prompt prefix": "負面通用提示詞前綴",1345 "Negative common prompt prefix": "負面通用提示詞前綴",
1345 "Character-specific prompt prefix": "角色特定提示詞前綴",1346 "Character-specific prompt prefix": "角色特定提示詞前綴",
1346 "Won't be used in groups.": "不會用在群組",1347 "Won't be used in groups.": "群聊中無效",
1347 "sd_character_prompt_placeholder": "描述該選擇角色的特徵。這些特徵將增加在通用提示詞前綴之後。\n例如:女性、綠色眼睛、棕色頭髮、粉紅色襯衫。",1348 "sd_character_prompt_placeholder": "描述該選擇角色的特徵。這些特徵將增加在通用提示詞前綴之後。\n例如:女性、綠色眼睛、棕色頭髮、粉紅色襯衫。",
1348 "Character-specific negative prompt prefix": "角色特定負面提示詞前綴",1349 "Character-specific negative prompt prefix": "角色特定負面提示詞前綴",
1349 "sd_character_negative_prompt_placeholder": "不應出現在選定角色上的任何特徵。這些特徵將增加在負面通用提示詞前綴之後。例如:珠寶、鞋子、眼鏡。",1350 "sd_character_negative_prompt_placeholder": "不應出現在選定角色上的任何特徵。這些特徵將增加在負面通用提示詞前綴之後。例如:珠寶、鞋子、眼鏡。",
1350 "Shareable": "可分享",1351 "Shareable": "可分享",
1351 "Image Prompt Templates": "圖片提示詞範本",1352 "Image Prompt Templates": "AI 算圖提示詞範本",
1352 "Vectors Model Warning": "向量模型警告",1353 "Vectors Model Warning": "向量模型警告",
1353 "Translate files into English before processing": "處理前將檔案翻譯成英文",1354 "Translate files into English before processing": "處理前將檔案翻譯成英文",
1354 "Manager Users": "管理使用者",1355 "Manager Users": "管理使用者",
@@ -1446,107 +1447,107 @@
1446 "(-1 for random)": "(-1 表示隨機)",1447 "(-1 for random)": "(-1 表示隨機)",
1447 "(Optional)": "(可選)",1448 "(Optional)": "(可選)",
1448 "(use _space": "(使用",1449 "(use _space": "(使用",
1449 "[no_connection_text]api_no_connection": "未連線⋯",1450 "api_no_connection": "未連線⋯",
1450 "[no_desc_text]No model description": "[無描述]",1451 "No model description": "[無描述]",
1451 "[no_items_text]openai_logit_bias_no_items": "無項目",1452 "openai_logit_bias_no_items": "無項目",
1452 "[placeholder]Any contents here will replace the default Post-History Instructions used for this character. (v2 specpost_history_instructions)": "此處填入的內容將取代該角色的默認聊天歷史後指示(Post-History Instructions)。\n(v2 specpost_history_instructions)",1453 "Any contents here will replace the default Post-History Instructions used for this character. (v2 specpost_history_instructions)": "此處填入的內容將取代該角色的默認聊天歷史後指示(Post-History Instructions)。\n(v2 specpost_history_instructions)",
1453 "[placeholder]comma delimited,no spaces between": "逗號分割,無需空格",1454 "comma delimited,no spaces between": "逗號分割,無需空格",
1454 "[placeholder]e.g. black-forest-labs/FLUX.1-dev": "例如:black-forest-labs/FLUX.1-dev",1455 "e.g. black-forest-labs/FLUX.1-dev": "例如:black-forest-labs/FLUX.1-dev",
1455 "[placeholder]Example: gpt-3.5-turbo": "例如:gpt-3.5-turbo",1456 "Example: gpt-3.5-turbo": "例如:gpt-3.5-turbo",
1456 "[placeholder]Example: http://localhost:1234/v1": "例如:http://localhost:1234/v1",1457 "Example: http://localhost:1234/v1": "例如:http://localhost:1234/v1",
1457 "[popup-button-crop]popup-button-crop": "裁剪",1458 "popup-button-crop": "裁剪",
1458 "[title](disabled when max recursion steps are used)": "(當最大遞歸步驟數使用時將停用)",1459 "(disabled when max recursion steps are used)": "(當最大遞歸步驟數使用時將停用)",
1459 "[title]0 = unlimited, 1 = scans once and doesn't recurse, 2 = scans once and recurses once, etc\n(disabled when min activations are used)": "0 = 無限制,1 = 掃描一次且不遞歸,2 = 掃描一次並遞歸一次,以此類推\n(使用最小啟動設定時將停用)",1460 "0 = unlimited, 1 = scans once and doesn't recurse, 2 = scans once and recurses once, etc\n(disabled when min activations are used)": "0 = 無限制,1 = 掃描一次且不遞歸,2 = 掃描一次並遞歸一次,以此類推\n(使用最小啟動設定時將停用)",
1460 "[title]A greedy, brute-force algorithm used in LLM sampling to find the most likely sequence of words or tokens. It expands multiple candidate sequences at once, maintaining a fixed number (beam width) of top sequences at each step.": "一種用於 LLM 抽樣的貪婪演算法,用於尋找最可能的單詞或標記序列。該方法會同時展開多個候選序列,並在每一步中保持固定數量的頂級序列(beam width)。",1461 "A greedy, brute-force algorithm used in LLM sampling to find the most likely sequence of words or tokens. It expands multiple candidate sequences at once, maintaining a fixed number (beam width) of top sequences at each step.": "一種用於 LLM 抽樣的貪婪演算法,用於尋找最可能的單詞或標記序列。該方法會同時展開多個候選序列,並在每一步中保持固定數量的頂級序列(beam width)。",
1461 "[title]A multiplicative factor to expand the overall area that the nodes take up.": "節點佔用區域擴展的倍數。",1462 "A multiplicative factor to expand the overall area that the nodes take up.": "節點佔用區域擴展的倍數。",
1462 "[title]Abort current image generation task": "終止目前的圖片生成任務",1463 "Abort current image generation task": "終止目前的圖片生成任務",
1463 "[title]Add Character and User names to a list of stopping strings.": "將角色和使用者角色名稱添加至停止字符列表。",1464 "Add Character and User names to a list of stopping strings.": "將角色和使用者角色名稱添加至停止字符列表。",
1464 "[title]Alignment for rank nodes.": "對排名節點的對齊方式。",1465 "Alignment for rank nodes.": "對排名節點的對齊方式。",
1465 "[title]Always show the node full info panel at the bottom left of the timeline view. When off, show it near the node.": "始終將節點的完整資訊面板顯示在時間軸視圖的左下角。關閉時,將顯示在節點附近。",1466 "Always show the node full info panel at the bottom left of the timeline view. When off, show it near the node.": "始終將節點的完整資訊面板顯示在時間軸視圖的左下角。關閉時,將顯示在節點附近。",
1466 "[title]Always show the node tooltip at the bottom left of the timeline view. When off, show it near the node.": "始終將節點的工具提示欄顯示在時間軸視圖的左下角。關閉時,將顯示在節點附近。",1467 "Always show the node tooltip at the bottom left of the timeline view. When off, show it near the node.": "始終將節點的工具提示欄顯示在時間軸視圖的左下角。關閉時,將顯示在節點附近。",
1467 "[title]Apply current sorting as Order": "應用此排序為順序",1468 "Apply current sorting as Order": "應用此排序為順序",
1468 "[title]Cap the number of entry activation recursions": "限制入口啟動的遞歸次數",1469 "Cap the number of entry activation recursions": "限制入口啟動的遞歸次數",
1469 "[title]Caption": "標題",1470 "Caption": "標題",
1470 "[title]Close popup": "關閉彈出視窗",1471 "Close popup": "關閉彈出視窗",
1471 "[title]Color configuration for Timelines when 'Use UI Theme' in Style Settings is off.": "關閉「使用介面主題」的時間線顏色。",1472 "Color configuration for Timelines when 'Use UI Theme' in Style Settings is off.": "關閉「使用介面主題」的時間線顏色。",
1472 "[title]context_allow_post_history_instructions": "在文本完成模式中包含聊天歷史後指示(Post-History Instructions),但可能導致不良輸出。",1473 "context_allow_post_history_instructions": "在文本完成模式中包含聊天歷史後指示(Post-History Instructions),但可能導致不良輸出。",
1473 "[title]Create a new connection profile": "建立新的連線設定檔",1474 "Create a new connection profile": "建立新的連線設定檔",
1474 "[title]Defines on importing cards which action should be chosen for importing its listed tags. 'Ask' will always display the dialog.": "定義導入卡片時應採取的動作。選擇「詢問」將始終顯示對話框。",1475 "Defines on importing cards which action should be chosen for importing its listed tags. 'Ask' will always display the dialog.": "定義導入卡片時應採取的動作。選擇「詢問」將始終顯示對話框。",
1475 "[title]delay_until_recursion_level": "定義遞迴掃描的延遲層級。\r最初僅匹配第一層(數字最小的層級)。\r未找到匹配時,下一層將成為可匹配的層級。\r此過程會重複,直到所有層級都被檢查完畢。\r與「延遲至遞歸」設定相關聯。",1476 "delay_until_recursion_level": "定義遞迴掃描的延遲層級。\r最初僅匹配第一層(數字最小的層級)。\r未找到匹配時,下一層將成為可匹配的層級。\r此過程會重複,直到所有層級都被檢查完畢。\r與「延遲至遞歸」設定相關聯。",
1476 "[title]Delete a connection profile": "刪除連線設定檔",1477 "Delete a connection profile": "刪除連線設定檔",
1477 "[title]Delete template": "刪除模板",1478 "Delete template": "刪除模板",
1478 "[title]Delete the template": "刪除此模板",1479 "Delete the template": "刪除此模板",
1479 "[title]Disabling is not recommended.": "不建議禁用。",1480 "Disabling is not recommended.": "不建議禁用。",
1480 "[title]Display swipe numbers for all messages, not just the last.": "顯示所有訊息的滑動編號,而不僅是最後一條訊息。",1481 "Display swipe numbers for all messages, not just the last.": "顯示所有訊息的滑動編號,而不僅是最後一條訊息。",
1481 "[title]Duplicate persona": "複製使用者角色",1482 "Duplicate persona": "複製使用者角色",
1482 "[title]Edit a connection profile": "編輯連線設定檔",1483 "Edit a connection profile": "編輯連線設定檔",
1483 "[title]Enable auto-select of input text in some text fields when clicking/selecting them. Applies to popup input textboxes, and possible other custom input fields.": "啟用自動選擇輸入框中的文本,適用於彈出輸入框及其他自定義輸入框。",1484 "Enable auto-select of input text in some text fields when clicking/selecting them. Applies to popup input textboxes, and possible other custom input fields.": "啟用自動選擇輸入框中的文本,適用於彈出輸入框及其他自定義輸入框。",
1484 "[title]Entries with a cooldown can't be activated N messages after being triggered.": "設有冷卻時間的條目於觸發後的 N 條訊息內無法再次啟用。",1485 "Entries with a cooldown can't be activated N messages after being triggered.": "設有冷卻時間的條目於觸發後的 N 條訊息內無法再次啟用。",
1485 "[title]Entries with a delay can't be activated until there are N messages present in the chat.": "有延遲的條目需等待聊天中出現 N 條訊息後才能啟用。",1486 "Entries with a delay can't be activated until there are N messages present in the chat.": "有延遲的條目需等待聊天中出現 N 條訊息後才能啟用。",
1486 "[title]Expand swipe nodes when the timeline view first opens, and whenever the graph is refreshed. When off, you can expand them by long-pressing a node, or by pressing the Toggle Swipes button.": "時間線視圖首次打開或刷新時展開滑動節點。關閉時可通過長按節點或點選「切換滑動」按鈕展開。",1487 "Expand swipe nodes when the timeline view first opens, and whenever the graph is refreshed. When off, you can expand them by long-pressing a node, or by pressing the Toggle Swipes button.": "時間線視圖首次打開或刷新時展開滑動節點。關閉時可通過長按節點或點選「切換滑動」按鈕展開。",
1487 "[title]Export Advanced Formatting settings": "匯出高級格式設定",1488 "Export Advanced Formatting settings": "匯出高級格式設定",
1488 "[title]Export template": "匯出模板",1489 "Export template": "匯出模板",
1489 "[title]Find similar characters": "尋找相似角色",1490 "Find similar characters": "尋找相似角色",
1490 "[title]Height of a node, in pixels at zoom level 1.0.": "縮放等級為 1.0 時的節點像素高度。",1491 "Height of a node, in pixels at zoom level 1.0.": "縮放等級為 1.0 時的節點像素高度。",
1491 "[title]How the automatic graph builder assigns a rank (layout depth) to graph nodes.": "自動圖表生成器分配圖節點等級(佈局深度)的方式。",1492 "How the automatic graph builder assigns a rank (layout depth) to graph nodes.": "自動圖表生成器分配圖節點等級(佈局深度)的方式。",
1492 "[title]If checked and the character card contains a Post-History Instructions override, use that instead": "勾選後,將使用角色卡中的聊天歷史後指示(Post-History Instructions)覆蓋。",1493 "If checked and the character card contains a Post-History Instructions override, use that instead": "勾選後,將使用角色卡中的聊天歷史後指示(Post-History Instructions)覆蓋。",
1493 "[title]Import Advanced Formatting settings": "匯入進階格式設定\n\n您也可以提供舊版檔案作為提示詞和上下文範本使用。",1494 "Import Advanced Formatting settings": "匯入進階格式設定\n\n您也可以提供舊版檔案作為提示詞和上下文範本使用。",
1494 "[title]Import template": "匯入模板",1495 "Import template": "匯入模板",
1495 "[title]In group chat, highlight the character(s) that are currently queued to generate responses and the order in which they will respond.": "在群組聊天中,突出顯示該生成回應的角色及順序。",1496 "In group chat, highlight the character(s) that are currently queued to generate responses and the order in which they will respond.": "在群組聊天中,突出顯示該生成回應的角色及順序。",
1496 "[title]Include names with each message into the context for scanning": "將每條訊息的名稱納入掃描上下文",1497 "Include names with each message into the context for scanning": "將每條訊息的名稱納入掃描上下文",
1497 "[title]Inserted before the first User's message": "插入到第一條使用者訊息前。",1498 "Inserted before the first User's message": "插入到第一條使用者訊息前。",
1498 "[title]instruct_enabled": "啟用指令模式(Instruct Mode)",1499 "instruct_enabled": "啟用指令模式(Instruct Mode)",
1499 "[title]instruct_last_input_sequence": "插入到最後一條使用者訊息之前。",1500 "instruct_last_input_sequence": "插入到最後一條使用者訊息之前。",
1500 "[title]instruct_template_activation_regex_desc": "連接 API 或選擇模型時,若模型名稱符合所提供的正規表達式,則自動啟動該指令模板(Instruct Template)。",1501 "instruct_template_activation_regex_desc": "連接 API 或選擇模型時,若模型名稱符合所提供的正規表達式,則自動啟動該指令模板(Instruct Template)。",
1501 "[title]Load Asset List": "載入資源列表",1502 "Load Asset List": "載入資源列表",
1502 "[title]load_asset_list_desc": "根據資源列表文件載入擴展及資源。\n\n該字段中的默認資源 URL 指向官方的擴展及資源的列表。\n可在此插入您的自定義資源列表。\n\n若需安裝單個第三方擴展,請使用右上角的「安裝擴展」按鈕。",1503 "load_asset_list_desc": "根據資源列表文件載入擴展及資源。\n\n該字段中的默認資源 URL 指向官方的擴展及資源的列表。\n可在此插入您的自定義資源列表。\n\n若需安裝單個第三方擴展,請使用右上角的「安裝擴展」按鈕。",
1503 "[title]markdown_hotkeys_desc": "啟用熱鍵以在某些文本輸入框中插入 Markdown 格式字符。詳見「/help hotkeys」。",1504 "markdown_hotkeys_desc": "啟用熱鍵以在某些文本輸入框中插入 Markdown 格式字符。詳見「/help hotkeys」。",
1504 "[title]Not all samplers supported.": "並非所有採樣器均受支援。",1505 "Not all samplers supported.": "並非所有採樣器均受支援。",
1505 "[title]Open the timeline view. Same as the slash command '/tl'.": "打開時間線視圖,與斜杠指令「/tl」相同。",1506 "Open the timeline view. Same as the slash command '/tl'.": "打開時間線視圖,與斜杠指令「/tl」相同。",
1506 "[title]Penalize sequences based on their length.": "根據序列長度進行懲罰。",1507 "Penalize sequences based on their length.": "根據序列長度進行懲罰。",
1507 "[title]Reload a connection profile": "重新載入連線設定檔",1508 "Reload a connection profile": "重新載入連線設定檔",
1508 "[title]Rename current preset": "重新命名此預設",1509 "Rename current preset": "重新命名此預設",
1509 "[title]Rename current prompt": "重新命名此提示詞",1510 "Rename current prompt": "重新命名此提示詞",
1510 "[title]Rename current template": "重新密名此模板",1511 "Rename current template": "重新密名此模板",
1511 "[title]Reset all Timelines settings to their default values.": "將所有時間軸設定重置為預設值。",1512 "Reset all Timelines settings to their default values.": "將所有時間軸設定重置為預設值。",
1512 "[title]Restore current prompt": "還原目前的提示詞",1513 "Restore current prompt": "還原目前的提示詞",
1513 "[title]Restore current template": "還原目前的模板",1514 "Restore current template": "還原目前的模板",
1514 "[title]Save prompt as": "另存提示詞為",1515 "Save prompt as": "另存提示詞為",
1515 "[title]Save template as": "另存模板為",1516 "Save template as": "另存模板為",
1516 "[title]sd_adetailer_face": "在生成過程中使用 ADetailer 臉部模型。需在後端安裝 ADetailer 擴展。",1517 "sd_adetailer_face": "在生成過程中使用 ADetailer 臉部模型。需在後端安裝 ADetailer 擴展。",
1517 "[title]sd_free_extend": "自動使用目前選定的 LLM 擴展自由模式主題提示詞(不包括肖像或背景)。",1518 "sd_free_extend": "自動使用目前選定的 LLM 擴展自由模式主題提示詞(不包括肖像或背景)。",
1518 "[title]sd_function_tool": "使用功能工具自動檢測意圖以生成圖片。",1519 "sd_function_tool": "使用功能工具自動檢測意圖以生成圖片。",
1519 "[title]Seed_desc": "用於生成確定性和可重現輸出的隨機種子。設定為 -1 時將使用隨機種子。",1520 "Seed_desc": "用於生成確定性和可重現輸出的隨機種子。設定為 -1 時將使用隨機種子。",
1520 "[title]Select your current Context Template": "選擇您目前的上下文模板",1521 "Select your current Context Template": "選擇您目前的上下文模板",
1521 "[title]Select your current Instruct Template": "選擇您目前的指令模板",1522 "Select your current Instruct Template": "選擇您目前的指令模板",
1522 "[title]Select your current System Prompt": "選擇您目前的系統提示詞",1523 "Select your current System Prompt": "選擇您目前的系統提示詞",
1523 "[title]Separation between adjacent edges in the same rank.": "同一層級中相鄰邊之間的間距。",1524 "Separation between adjacent edges in the same rank.": "同一層級中相鄰邊之間的間距。",
1524 "[title]Separation between adjacent nodes in the same rank.": "同一層級中相鄰節點之間的間距。",1525 "Separation between adjacent nodes in the same rank.": "同一層級中相鄰節點之間的間距。",
1525 "[title]Separation between each rank in the layout.": "佈局中各層級之間的間距。",1526 "Separation between each rank in the layout.": "佈局中各層級之間的間距。",
1526 "[title]Settings for the visual appearance of the Timelines graph.": "時間線圖形的視覺外觀設置。",1527 "Settings for the visual appearance of the Timelines graph.": "時間線圖形的視覺外觀設置。",
1527 "[title]Show a button in the input area to ask the AI to impersonate your character for a single message": "在輸入框中添加按鈕,讓 AI 模仿您的角色身份發送一則訊息。",1528 "Show a button in the input area to ask the AI to impersonate your character for a single message": "在輸入框中添加按鈕,讓 AI 模仿您的角色身份發送一則訊息。",
1528 "[title]Show a legend for colors corresponding to different characters and chat checkpoints.": "顯示一個圖例,標註不同角色和對話檢查點對應的顏色。",1529 "Show a legend for colors corresponding to different characters and chat checkpoints.": "顯示一個圖例,標註不同角色和對話檢查點對應的顏色。",
1529 "[title]Show the AI character's avatar as the graph root node. When off, the root node is blank.": "將 AI 角色的頭像作為圖形的根節點;關閉時,根節點為空。",1530 "Show the AI character's avatar as the graph root node. When off, the root node is blank.": "將 AI 角色的頭像作為圖形的根節點;關閉時,根節點為空。",
1530 "[title]Sticky entries will stay active for N messages after being triggered.": "觸發後,置頂條目將在接下來的 N 條訊息中保持活躍。",1531 "Sticky entries will stay active for N messages after being triggered.": "觸發後,置頂條目將在接下來的 N 條訊息中保持活躍。",
1531 "[title]stscript_parser_flag_replace_getvar_label": "防止 {{getvar::}} 和 {{getglobalvar::}} 巨集的字面巨集樣值被自動解析。\n例如,{{newline}} 將保持為字面字串 {{newline}}。\n\n(此功能通過內部將 {{getvar::}} 和 {{getglobalvar::}} 巨集替換為具範圍的變數來實現。)",1532 "stscript_parser_flag_replace_getvar_label": "防止 {{getvar::}} 和 {{getglobalvar::}} 巨集的字面巨集樣值被自動解析。\n例如,{{newline}} 將保持為字面字串 {{newline}}。\n\n(此功能通過內部將 {{getvar::}} 和 {{getglobalvar::}} 巨集替換為具範圍的變數來實現。)",
1532 "[title]Style and routing of graph edges.": "圖形邊的樣式和路徑。",1533 "Style and routing of graph edges.": "圖形邊的樣式和路徑。",
1533 "[title]Swap width and height": "交換寬度與高度",1534 "Swap width and height": "交換寬度與高度",
1534 "[title]Swipe left": "向左滑動",1535 "Swipe left": "向左滑動",
1535 "[title]Swipe right": "向右滑動",1536 "Swipe right": "向右滑動",
1536 "[title]Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry": "切換角色/標籤篩選,將列出的角色和標籤從此條目的匹配中排除",1537 "Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry": "切換角色/標籤篩選,將列出的角色和標籤從此條目的匹配中排除",
1537 "[title]sysprompt_enabled": "啟用系統提示詞",1538 "sysprompt_enabled": "啟用系統提示詞",
1538 "[title]The number of sequences generated at each step with Beam Search.": "在 Beam Search 中每一步生成的序列數量。",1539 "The number of sequences generated at each step with Beam Search.": "在 Beam Search 中每一步生成的序列數量。",
1539 "[title]The visual appearance of a node in the graph.": "圖形中節點的視覺外觀。",1540 "The visual appearance of a node in the graph.": "圖形中節點的視覺外觀。",
1540 "[title]Update a connection profile": "更新連線設定檔",1541 "Update a connection profile": "更新連線設定檔",
1541 "[title]Update current prompt": "更新此提示詞",1542 "Update current prompt": "更新此提示詞",
1542 "[title]Update current template": "更新此模板",1543 "Update current template": "更新此模板",
1543 "[title]Use GPU acceleration for positioning the full info panel that appears when you click a node. If the tooltip arrow tends to disappear, turning this off may help.": "啟用 GPU 加速來定位點擊節點時出現的完整資訊面板。若發現工具提示箭頭經常消失,可考慮關閉此功能。",1544 "Use GPU acceleration for positioning the full info panel that appears when you click a node. If the tooltip arrow tends to disappear, turning this off may help.": "啟用 GPU 加速來定位點擊節點時出現的完整資訊面板。若發現工具提示箭頭經常消失,可考慮關閉此功能。",
1544 "[title]Use the colors of the ST GUI theme, instead of the colors configured in Color Settings specifically for this extension.": "以 ST GUI 主題的顏色,取代「顏色設定」中針對此擴展特別配置的顏色。",1545 "Use the colors of the ST GUI theme, instead of the colors configured in Color Settings specifically for this extension.": "以 ST GUI 主題的顏色,取代「顏色設定」中針對此擴展特別配置的顏色。",
1545 "[title]View connection profile details": "查看連線設定檔詳情",1546 "View connection profile details": "查看連線設定檔詳情",
1546 "[title]When enabled, nodes that have swipes splitting off of them will appear subtly larger, in addition to having the double border.": "啟用後,具分支滑動的節點將顯示雙重邊框,還會略微放大。",1547 "When enabled, nodes that have swipes splitting off of them will appear subtly larger, in addition to having the double border.": "啟用後,具分支滑動的節點將顯示雙重邊框,還會略微放大。",
1547 "[title]WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized": "世界資訊條目狀態:\\r🔵 恆定\\r🟢 正常\\r🔗 向量化",1548 "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized": "世界資訊條目狀態:\\r🔵 恆定\\r🟢 正常\\r🔗 向量化",
1548 "[title]Width of a node, in pixels at zoom level 1.0.": "縮放等級為 1.0 時,節點的像素寬度。",1549 "Width of a node, in pixels at zoom level 1.0.": "縮放等級為 1.0 時,節點的像素寬度。",
1549 "[title]world_button_title": "角色背景設定\\n\\n點擊以載入\\nShift+ 點擊開啟「連結至世界資訊」彈窗",1550 "world_button_title": "角色背景設定\\n\\n點擊以載入\\nShift+ 點擊開啟「連結至世界資訊」彈窗",
1550 "# of Beams": "# of Beams",1551 "# of Beams": "# of Beams",
1551 "01.AI API Key": "01.AI API 金鑰",1552 "01.AI API Key": "01.AI API 金鑰",
1552 "01.AI Model": "01.AI 模型",1553 "01.AI Model": "01.AI 模型",
@@ -1573,8 +1574,8 @@
1573 "at the end of the URL!": "在 URL 末尾!",1574 "at the end of the URL!": "在 URL 末尾!",
1574 "Audio Playback Speed": "音檔播放速度",1575 "Audio Playback Speed": "音檔播放速度",
1575 "Auto-select Input Text": "自動選擇輸入文本",1576 "Auto-select Input Text": "自動選擇輸入文本",
1576 "Automatically caption images": "自動為圖片添加字幕",1577 "Automatically caption images": "自動為圖片添加註解",
1577 "Auxiliary": "輔助",1578 "Auxiliary": "輔助提示詞",
1578 "Background Image": "背景圖片",1579 "Background Image": "背景圖片",
1579 "Block Entropy API Key": "Block Entropy API 金鑰",1580 "Block Entropy API Key": "Block Entropy API 金鑰",
1580 "Can be set manually or with an _space": "可以手動設置或使用 _space",1581 "Can be set manually or with an _space": "可以手動設置或使用 _space",
@@ -1610,7 +1611,7 @@
1610 "Delay until recursion (can only be activated on recursive checking)": "遞迴掃描延遲(僅在啟用遞迴掃描時可用)",1611 "Delay until recursion (can only be activated on recursive checking)": "遞迴掃描延遲(僅在啟用遞迴掃描時可用)",
1611 "Do not proceed if you do not agree to this!": "若不同意此條款,請勿繼續!",1612 "Do not proceed if you do not agree to this!": "若不同意此條款,請勿繼續!",
1612 "Edge Color": "邊緣顏色",1613 "Edge Color": "邊緣顏色",
1613 "Edit captions before saving": "在保存前編輯字幕",1614 "Edit captions before saving": "在保存前編輯註解",
1614 "Enable for files": "為文件啟用",1615 "Enable for files": "為文件啟用",
1615 "Enable for World Info": "為世界資訊啟用",1616 "Enable for World Info": "為世界資訊啟用",
1616 "enable_functions_desc_1": "允許使用",1617 "enable_functions_desc_1": "允許使用",
@@ -1651,6 +1652,7 @@
1651 "Horde": "Horde",1652 "Horde": "Horde",
1652 "HuggingFace Token": "HuggingFace 符元",1653 "HuggingFace Token": "HuggingFace 符元",
1653 "Image Captioning": "圖片標註",1654 "Image Captioning": "圖片標註",
1655 "Generate Caption": "生成圖片說明",
1654 "Image Type - talkinghead (extras)": "圖片類型 - talkinghead(額外選項)",1656 "Image Type - talkinghead (extras)": "圖片類型 - talkinghead(額外選項)",
1655 "Injection Position": "插入位置",1657 "Injection Position": "插入位置",
1656 "Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.": "插入位置(與提示詞管理器中的其他提示相比)或聊天中的深度位置。",1658 "Injection position. Relative (to other prompts in prompt manager) or In-chat @ Depth.": "插入位置(與提示詞管理器中的其他提示相比)或聊天中的深度位置。",
@@ -1694,7 +1696,7 @@
1694 "Only used when Main API or WebLLM Extension is selected.": "僅在選擇主要 API 或 WebLLM 擴展時使用。",1696 "Only used when Main API or WebLLM Extension is selected.": "僅在選擇主要 API 或 WebLLM 擴展時使用。",
1695 "Open a chat to see the character expressions.": "開啟聊天以查看角色表情。",1697 "Open a chat to see the character expressions.": "開啟聊天以查看角色表情。",
1696 "Post-History Instructions": "聊天歷史後指示",1698 "Post-History Instructions": "聊天歷史後指示",
1697 "Prefer Character Card Instructions": "偏好角色卡聊天歷史後指示",1699 "Prefer Character Card Instructions": "角色卡聊天歷史後指示優先",
1698 "Prioritize": "優先處理",1700 "Prioritize": "優先處理",
1699 "Prompt Content": "提示詞內容",1701 "Prompt Content": "提示詞內容",
1700 "prompt_manager_in_chat": "聊天中的提示詞管理",1702 "prompt_manager_in_chat": "聊天中的提示詞管理",
@@ -1734,23 +1736,23 @@
1734 "Select with Tab or Enter": "按 Tab 或 Enter 選擇",1736 "Select with Tab or Enter": "按 Tab 或 Enter 選擇",
1735 "Separators as Stop Strings": "以分隔符作為停止字串",1737 "Separators as Stop Strings": "以分隔符作為停止字串",
1736 "Set the default and fallback expression being used when no matching expression is found.": "設定在無法配對到表情時所使用的預設和替代圖片。",1738 "Set the default and fallback expression being used when no matching expression is found.": "設定在無法配對到表情時所使用的預設和替代圖片。",
1737 "Set your API keys and endpoints in the API Connections tab first.": "請先在「API 連接」頁面中設定您的 API 密鑰和端點。",1739 "Set your API keys and endpoints in the API Connections tab first.": "請先在「API 連接」頁面中設定您的 API 金鑰和端點。",
1738 "Show default images (emojis) if sprite missing": "無對應圖片時,顯示為預設表情符號(emoji)",1740 "Show default images (emojis) if sprite missing": "無對應圖片時,顯示為預設表情符號(emoji)",
1739 "Show group chat queue": "顯示群組聊天隊列",1741 "Show group chat queue": "顯示群組聊天隊列",
1740 "Size threshold (KB)": "大小閾值(KB)",1742 "Size threshold (KB)": "大小閾值(KB)",
1741 "Slash Command": "斜線命令",1743 "Slash Command": "斜線命令",
1742 "space_ slash command.": "斜線命令。",1744 "space_ slash command.": "斜線命令。",
1743 "Sprite Folder Override": "表情立繪資料夾覆蓋",1745 "Sprite Folder Override": "表情立繪資料夾覆蓋",
1744 "Sprite set:": "表情集:",1746 "Sprite set:": "立繪組:",
1745 "Show Gallery": "查看畫廊",1747 "Show Gallery": "查看畫廊",
1746 "Sticky": "固定",1748 "Sticky": "固定",
1747 "Style Preset": "預設樣式",1749 "Style Preset": "預設樣式",
1748 "Summarize chat messages for vector generation": "摘要聊天訊息以進行向量化處理",1750 "Summarize chat messages for vector generation": "摘要聊天訊息以進行向量化處理",
1749 "Summarize chat messages when sending": "傳送時摘要聊天內容",1751 "Summarize chat messages when sending": "傳送時摘要聊天內容",
1750 "Swipe # for All Messages": "為所有訊息分配滑動編號 #",1752 "Swipe # for All Messages": "為所有訊息分配滑動編號 #",
1751 "System Message Sequences": "系統訊息順序",1753 "System Message Sequences": "系統訊息序列",
1752 "System Prefix": "系統訊息前綴",1754 "System Prefix": "系統訊息前綴",
1753 "System Prompt Sequences": "系統提示詞順序",1755 "System Prompt Sequences": "系統提示詞序列",
1754 "System Suffix": "系統訊息後綴",1756 "System Suffix": "系統訊息後綴",
1755 "Tabby Model": "Tabby 模型",1757 "Tabby Model": "Tabby 模型",
1756 "tag_import_all": "全部匯入",1758 "tag_import_all": "全部匯入",
@@ -1767,9 +1769,9 @@
1767 "Upload sprite pack (ZIP)": "打包上傳立繪(ZIP 格式)",1769 "Upload sprite pack (ZIP)": "打包上傳立繪(ZIP 格式)",
1768 "Use a forward slash to specify a subfolder. Example: _space": "使用「/」來設置子目錄,例如:_space",1770 "Use a forward slash to specify a subfolder. Example: _space": "使用「/」來設置子目錄,例如:_space",
1769 "Use ADetailer (Face)": "使用 ADetailer 進行臉部處理。",1771 "Use ADetailer (Face)": "使用 ADetailer 進行臉部處理。",
1770 "Use an admin API key.": "使用管理員的 API 密鑰。",1772 "Use an admin API key.": "使用管理員的 API 金鑰。",
1771 "Use global": "啟用全域設定",1773 "Use global": "啟用全域設定",
1772 "User Message Sequences": "使用者訊息順序",1774 "User Message Sequences": "使用者訊息序列",
1773 "User Node Color": "使用者節點顏色",1775 "User Node Color": "使用者節點顏色",
1774 "User Prefix": "使用者訊息前綴",1776 "User Prefix": "使用者訊息前綴",
1775 "User Suffix": "使用者訊息後綴",1777 "User Suffix": "使用者訊息後綴",
@@ -1787,5 +1789,8 @@
1787 "Will be used if the API doesnt support JSON schemas or function calling.": "若 API 不支持 JSON 模式或函數調用,將使用此設定。",1789 "Will be used if the API doesnt support JSON schemas or function calling.": "若 API 不支持 JSON 模式或函數調用,將使用此設定。",
1788 "World Info settings": "世界資訊設定",1790 "World Info settings": "世界資訊設定",
1789 "You are in offline mode. Click on the image below to set the expression.": "您目前為離線狀態,請點擊下方圖片進行表情設定。",1791 "You are in offline mode. Click on the image below to set the expression.": "您目前為離線狀態,請點擊下方圖片進行表情設定。",
1790 "You can find your API key in the Stability AI dashboard.": "API 金鑰可在 Stability AI 儀表板中查看。"1792 "You can find your API key in the Stability AI dashboard.": "API 金鑰可在 Stability AI 儀表板中查看。",
1793 "Stop Inspecting": "停止檢查",
1794 "Inspect Prompts": "檢查提示詞",
1795 "Toggle prompt inspection": "切換提示詞檢查"
1791}1796}
public/script.js+121 -78
@@ -10,6 +10,7 @@ import {
10 SVGInject,10 SVGInject,
11 Popper,11 Popper,
12 initLibraryShims,12 initLibraryShims,
13 slideToggle,
13 default as libs,14 default as libs,
14} from './lib.js';15} from './lib.js';
1516
@@ -549,6 +550,7 @@ let optionsPopper = Popper.createPopper(document.getElementById('options_button'
549let exportPopper = Popper.createPopper(document.getElementById('export_button'), document.getElementById('export_format_popup'), {550let exportPopper = Popper.createPopper(document.getElementById('export_button'), document.getElementById('export_format_popup'), {
550 placement: 'left',551 placement: 'left',
551});552});
553let isExportPopupOpen = false;
552554
553// Saved here for performance reasons555// Saved here for performance reasons
554const messageTemplate = $('#message_template .mes');556const messageTemplate = $('#message_template .mes');
@@ -895,6 +897,13 @@ export function getRequestHeaders() {
895 };897 };
896}898}
897899
900export function getSlideToggleOptions() {
901 return {
902 miliseconds: animation_duration * 1.5,
903 transitionFunction: animation_duration > 0 ? 'ease-in-out' : 'step-start',
904 };
905}
906
898$.ajaxPrefilter((options, originalOptions, xhr) => {907$.ajaxPrefilter((options, originalOptions, xhr) => {
899 xhr.setRequestHeader('X-CSRF-Token', token);908 xhr.setRequestHeader('X-CSRF-Token', token);
900});909});
@@ -1173,7 +1182,7 @@ async function getStatusTextgen() {
1173 return resultCheckStatus();1182 return resultCheckStatus();
1174 }1183 }
11751184
1176 if (textgen_settings.type == textgen_types.OOBA && textgen_settings.bypass_status_check) {1185 if ([textgen_types.GENERIC, textgen_types.OOBA].includes(textgen_settings.type) && textgen_settings.bypass_status_check) {
1177 setOnlineStatus('Status check bypassed');1186 setOnlineStatus('Status check bypassed');
1178 return resultCheckStatus();1187 return resultCheckStatus();
1179 }1188 }
@@ -1223,7 +1232,7 @@ async function getStatusTextgen() {
1223 setOnlineStatus(textgen_settings.tabby_model || data?.result);1232 setOnlineStatus(textgen_settings.tabby_model || data?.result);
1224 } else if (textgen_settings.type === textgen_types.GENERIC) {1233 } else if (textgen_settings.type === textgen_types.GENERIC) {
1225 loadGenericModels(data?.data);1234 loadGenericModels(data?.data);
1226 setOnlineStatus(textgen_settings.generic_model || 'Connected');1235 setOnlineStatus(textgen_settings.generic_model || data?.result || 'Connected');
1227 } else {1236 } else {
1228 setOnlineStatus(data?.result);1237 setOnlineStatus(data?.result);
1229 }1238 }
@@ -4579,9 +4588,12 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
4579 const shouldDeleteMessage = type !== 'swipe' && ['', '...'].includes(lastMessage?.mes) && ['', '...'].includes(streamingProcessor?.result);4588 const shouldDeleteMessage = type !== 'swipe' && ['', '...'].includes(lastMessage?.mes) && ['', '...'].includes(streamingProcessor?.result);
4580 hasToolCalls && shouldDeleteMessage && await deleteLastMessage();4589 hasToolCalls && shouldDeleteMessage && await deleteLastMessage();
4581 const invocationResult = await ToolManager.invokeFunctionTools(streamingProcessor.toolCalls);4590 const invocationResult = await ToolManager.invokeFunctionTools(streamingProcessor.toolCalls);
4591 const shouldStopGeneration = (!invocationResult.invocations.length && shouldDeleteMessage) || invocationResult.stealthCalls.length;
4582 if (hasToolCalls) {4592 if (hasToolCalls) {
4583 if (!invocationResult.invocations.length && shouldDeleteMessage) {4593 if (shouldStopGeneration) {
4594 if (Array.isArray(invocationResult.errors) && invocationResult.errors.length) {
4584 ToolManager.showToolCallError(invocationResult.errors);4595 ToolManager.showToolCallError(invocationResult.errors);
4596 }
4585 unblockGeneration(type);4597 unblockGeneration(type);
4586 generatedPromptCache = '';4598 generatedPromptCache = '';
4587 streamingProcessor = null;4599 streamingProcessor = null;
@@ -4681,9 +4693,12 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
4681 const shouldDeleteMessage = type !== 'swipe' && ['', '...'].includes(getMessage);4693 const shouldDeleteMessage = type !== 'swipe' && ['', '...'].includes(getMessage);
4682 hasToolCalls && shouldDeleteMessage && await deleteLastMessage();4694 hasToolCalls && shouldDeleteMessage && await deleteLastMessage();
4683 const invocationResult = await ToolManager.invokeFunctionTools(data);4695 const invocationResult = await ToolManager.invokeFunctionTools(data);
4696 const shouldStopGeneration = (!invocationResult.invocations.length && shouldDeleteMessage) || invocationResult.stealthCalls.length;
4684 if (hasToolCalls) {4697 if (hasToolCalls) {
4685 if (!invocationResult.invocations.length && shouldDeleteMessage) {4698 if (shouldStopGeneration) {
4699 if (Array.isArray(invocationResult.errors) && invocationResult.errors.length) {
4686 ToolManager.showToolCallError(invocationResult.errors);4700 ToolManager.showToolCallError(invocationResult.errors);
4701 }
4687 unblockGeneration(type);4702 unblockGeneration(type);
4688 generatedPromptCache = '';4703 generatedPromptCache = '';
4689 return;4704 return;
@@ -9203,40 +9218,48 @@ function doDrawerOpenClick() {
9203 * @returns {void}9218 * @returns {void}
9204 */9219 */
9205function doNavbarIconClick() {9220function doNavbarIconClick() {
9206 var icon = $(this).find('.drawer-icon');9221 const icon = $(this).find('.drawer-icon');
9207 var drawer = $(this).parent().find('.drawer-content');9222 const drawer = $(this).parent().find('.drawer-content');
9208 if (drawer.hasClass('resizing')) { return; }9223 if (drawer.hasClass('resizing')) { return; }
9209 var drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer');9224 const drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer');
9210 let targetDrawerID = $(this).parent().find('.drawer-content').attr('id');9225 const targetDrawerID = $(this).parent().find('.drawer-content').attr('id');
9211 const pinnedDrawerClicked = drawer.hasClass('pinnedOpen');9226 const pinnedDrawerClicked = drawer.hasClass('pinnedOpen');
92129227
9213 if (!drawerWasOpenAlready) { //to open the drawer9228 if (!drawerWasOpenAlready) { //to open the drawer
9214 $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {9229 $('.openDrawer').not('.pinnedOpen').addClass('resizing').each((_, el) => {
9215 await delay(50); $(this).closest('.drawer-content').removeClass('resizing');9230 slideToggle(el, {
9231 ...getSlideToggleOptions(),
9232 onAnimationEnd: function (el) {
9233 el.closest('.drawer-content').classList.remove('resizing');
9234 },
9235 });
9216 });9236 });
9217 $('.openIcon').toggleClass('closedIcon openIcon');9237 $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon');
9218 $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');9238 $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');
9219 icon.toggleClass('openIcon closedIcon');9239 icon.toggleClass('openIcon closedIcon');
9220 drawer.toggleClass('openDrawer closedDrawer');9240 drawer.toggleClass('openDrawer closedDrawer');
92219241
9222 //console.log(targetDrawerID);9242 //console.log(targetDrawerID);
9223 if (targetDrawerID === 'right-nav-panel') {9243 if (targetDrawerID === 'right-nav-panel') {
9224 $(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle({9244 $(this).closest('.drawer').find('.drawer-content').addClass('resizing').each((_, el) => {
9225 duration: 200,9245 slideToggle(el, {
9226 easing: 'swing',9246 ...getSlideToggleOptions(),
9227 start: function () {9247 elementDisplayStyle: 'flex',
9228 jQuery(this).css('display', 'flex'); //flex needed to make charlist scroll9248 onAnimationEnd: function (el) {
9229 },9249 el.closest('.drawer-content').classList.remove('resizing');
9230 complete: async function () {
9231 favsToHotswap();9250 favsToHotswap();
9232 await delay(50);
9233 $(this).closest('.drawer-content').removeClass('resizing');
9234 $('#rm_print_characters_block').trigger('scroll');9251 $('#rm_print_characters_block').trigger('scroll');
9235 },9252 },
9236 });9253 });
9254 });
9237 } else {9255 } else {
9238 $(this).closest('.drawer').find('.drawer-content').addClass('resizing').slideToggle(200, 'swing', async function () {9256 $(this).closest('.drawer').find('.drawer-content').addClass('resizing').each((_, el) => {
9239 await delay(50); $(this).closest('.drawer-content').removeClass('resizing');9257 slideToggle(el, {
9258 ...getSlideToggleOptions(),
9259 onAnimationEnd: function (el) {
9260 el.closest('.drawer-content').classList.remove('resizing');
9261 },
9262 });
9240 });9263 });
9241 }9264 }
92429265
@@ -9252,13 +9275,23 @@ function doNavbarIconClick() {
9252 icon.toggleClass('closedIcon openIcon');9275 icon.toggleClass('closedIcon openIcon');
92539276
9254 if (pinnedDrawerClicked) {9277 if (pinnedDrawerClicked) {
9255 $(drawer).addClass('resizing').slideToggle(200, 'swing', async function () {9278 $(drawer).addClass('resizing').each((_, el) => {
9256 await delay(50); $(this).removeClass('resizing');9279 slideToggle(el, {
9280 ...getSlideToggleOptions(),
9281 onAnimationEnd: function (el) {
9282 el.classList.remove('resizing');
9283 },
9284 });
9257 });9285 });
9258 }9286 }
9259 else {9287 else {
9260 $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', async function () {9288 $('.openDrawer').not('.pinnedOpen').addClass('resizing').each((_, el) => {
9261 await delay(50); $(this).closest('.drawer-content').removeClass('resizing');9289 slideToggle(el, {
9290 ...getSlideToggleOptions(),
9291 onAnimationEnd: function (el) {
9292 el.closest('.drawer-content').classList.remove('resizing');
9293 },
9294 });
9262 });9295 });
9263 }9296 }
92649297
@@ -10080,20 +10113,21 @@ jQuery(async function () {
10080 await getStatusNovel();10113 await getStatusNovel();
10081 });10114 });
1008210115
10083 var button = $('#options_button');10116 const button = $('#options_button');
10084 var menu = $('#options');10117 const menu = $('#options');
10118 let isOptionsMenuVisible = false;
1008510119
10086 function showMenu() {10120 function showMenu() {
10087 showBookmarksButtons();10121 showBookmarksButtons();
10088 // menu.stop()
10089 menu.fadeIn(animation_duration);10122 menu.fadeIn(animation_duration);
10090 optionsPopper.update();10123 optionsPopper.update();
10124 isOptionsMenuVisible = true;
10091 }10125 }
1009210126
10093 function hideMenu() {10127 function hideMenu() {
10094 // menu.stop();
10095 menu.fadeOut(animation_duration);10128 menu.fadeOut(animation_duration);
10096 optionsPopper.update();10129 optionsPopper.update();
10130 isOptionsMenuVisible = false;
10097 }10131 }
1009810132
10099 function isMouseOverButtonOrMenu() {10133 function isMouseOverButtonOrMenu() {
@@ -10101,26 +10135,15 @@ jQuery(async function () {
10101 }10135 }
1010210136
10103 button.on('click', function () {10137 button.on('click', function () {
10104 if (menu.is(':visible')) {10138 if (isOptionsMenuVisible) {
10105 hideMenu();10139 hideMenu();
10106 } else {10140 } else {
10107 showMenu();10141 showMenu();
10108 }10142 }
10109 });10143 });
10110 button.on('blur', function () {
10111 //delay to prevent menu hiding when mouse leaves button into menu
10112 setTimeout(() => {
10113 if (!isMouseOverButtonOrMenu()) { hideMenu(); }
10114 }, 100);
10115 });
10116 menu.on('blur', function () {
10117 //delay to prevent menu hide when mouseleaves menu into button
10118 setTimeout(() => {
10119 if (!isMouseOverButtonOrMenu()) { hideMenu(); }
10120 }, 100);
10121 });
10122 $(document).on('click', function () {10144 $(document).on('click', function () {
10123 if (!isMouseOverButtonOrMenu() && menu.is(':visible')) { hideMenu(); }10145 if (!isOptionsMenuVisible) return;
10146 if (!isMouseOverButtonOrMenu()) { hideMenu(); }
10124 });10147 });
1012510148
10126 /* $('#set_chat_scenario').on('click', setScenarioOverride); */10149 /* $('#set_chat_scenario').on('click', setScenarioOverride); */
@@ -10516,22 +10539,28 @@ jQuery(async function () {
10516 });10539 });
1051710540
10518 $(document).on('click', '.extraMesButtonsHint', function (e) {10541 $(document).on('click', '.extraMesButtonsHint', function (e) {
10519 const elmnt = e.target;10542 const $hint = $(e.target);
10520 $(elmnt).transition({10543 const $buttons = $hint.siblings('.extraMesButtons');
10544
10545 $hint.transition({
10521 opacity: 0,10546 opacity: 0,
10522 duration: animation_duration,10547 duration: animation_duration,
10523 easing: 'ease-in-out',10548 easing: animation_easing,
10524 });10549 complete: function () {
10525 setTimeout(function () {10550 $hint.hide();
10526 $(elmnt).hide();10551 $buttons
10527 $(elmnt).siblings('.extraMesButtons').css('opcacity', '0');10552 .addClass('visible')
10528 $(elmnt).siblings('.extraMesButtons').css('display', 'flex');10553 .css({
10529 $(elmnt).siblings('.extraMesButtons').transition({10554 opacity: 0,
10555 display: 'flex',
10556 })
10557 .transition({
10530 opacity: 1,10558 opacity: 1,
10531 duration: animation_duration,10559 duration: animation_duration,
10532 easing: 'ease-in-out',10560 easing: animation_easing,
10561 });
10562 },
10533 });10563 });
10534 }, animation_duration);
10535 });10564 });
1053610565
10537 $(document).on('click', function (e) {10566 $(document).on('click', function (e) {
@@ -10542,19 +10571,32 @@ jQuery(async function () {
1054210571
10543 // Check if the click was outside the relevant elements10572 // Check if the click was outside the relevant elements
10544 if (!$(e.target).closest('.extraMesButtons, .extraMesButtonsHint').length) {10573 if (!$(e.target).closest('.extraMesButtons, .extraMesButtonsHint').length) {
10574 const $visibleButtons = $('.extraMesButtons.visible');
10575
10576 if (!$visibleButtons.length) {
10577 return;
10578 }
10579
10580 const $hiddenHints = $('.extraMesButtonsHint:hidden');
10581
10545 // Transition out the .extraMesButtons first10582 // Transition out the .extraMesButtons first
10546 $('.extraMesButtons:visible').transition({10583 $visibleButtons.transition({
10547 opacity: 0,10584 opacity: 0,
10548 duration: animation_duration,10585 duration: animation_duration,
10549 easing: 'ease-in-out',10586 easing: animation_easing,
10550 complete: function () {10587 complete: function () {
10551 $(this).hide(); // Hide the .extraMesButtons after the transition10588 // Hide the .extraMesButtons after the transition
10589 $(this)
10590 .hide()
10591 .removeClass('visible');
1055210592
10553 // Transition the .extraMesButtonsHint back in10593 // Transition the .extraMesButtonsHint back in
10554 $('.extraMesButtonsHint:not(:visible)').show().transition({10594 $hiddenHints
10555 opacity: .3,10595 .show()
10596 .transition({
10597 opacity: 0.3,
10556 duration: animation_duration,10598 duration: animation_duration,
10557 easing: 'ease-in-out',10599 easing: animation_easing,
10558 complete: function () {10600 complete: function () {
10559 $(this).css('opacity', '');10601 $(this).css('opacity', '');
10560 },10602 },
@@ -10742,8 +10784,9 @@ jQuery(async function () {
10742 }10784 }
10743 });10785 });
1074410786
10745 $('#export_button').on('click', function (e) {10787 $('#export_button').on('click', function () {
10746 $('#export_format_popup').toggle();10788 isExportPopupOpen = !isExportPopupOpen;
10789 $('#export_format_popup').toggle(isExportPopupOpen);
10747 exportPopper.update();10790 exportPopper.update();
10748 });10791 });
1074910792
@@ -10754,6 +10797,10 @@ jQuery(async function () {
10754 return;10797 return;
10755 }10798 }
1075610799
10800 $('#export_format_popup').hide();
10801 isExportPopupOpen = false;
10802 exportPopper.update();
10803
10757 // Save before exporting10804 // Save before exporting
10758 await createOrEditCharacter();10805 await createOrEditCharacter();
10759 const body = { format, avatar_url: characters[this_chid].avatar };10806 const body = { format, avatar_url: characters[this_chid].avatar };
@@ -10775,9 +10822,6 @@ jQuery(async function () {
10775 URL.revokeObjectURL(a.href);10822 URL.revokeObjectURL(a.href);
10776 document.body.removeChild(a);10823 document.body.removeChild(a);
10777 }10824 }
10778
10779
10780 $('#export_format_popup').hide();
10781 });10825 });
10782 //**************************CHAT IMPORT EXPORT*************************//10826 //**************************CHAT IMPORT EXPORT*************************//
10783 $('#chat_import_button').click(function () {10827 $('#chat_import_button').click(function () {
@@ -10849,15 +10893,18 @@ jQuery(async function () {
10849 });10893 });
1085010894
10851 $(document).on('click', '.drawer-opener', doDrawerOpenClick);10895 $(document).on('click', '.drawer-opener', doDrawerOpenClick);
10896
10852 $('.drawer-toggle').on('click', doNavbarIconClick);10897 $('.drawer-toggle').on('click', doNavbarIconClick);
1085310898
10854 $('html').on('touchstart mousedown', function (e) {10899 $('html').on('touchstart mousedown', function (e) {
10855 var clickTarget = $(e.target);10900 var clickTarget = $(e.target);
1085610901
10857 if ($('#export_format_popup').is(':visible')10902 if (isExportPopupOpen
10858 && clickTarget.closest('#export_button').length == 010903 && clickTarget.closest('#export_button').length == 0
10859 && clickTarget.closest('#export_format_popup').length == 0) {10904 && clickTarget.closest('#export_format_popup').length == 0) {
10860 $('#export_format_popup').hide();10905 $('#export_format_popup').hide();
10906 isExportPopupOpen = false;
10907 exportPopper.update();
10861 }10908 }
1086210909
10863 const forbiddenTargets = [10910 const forbiddenTargets = [
@@ -10882,12 +10929,16 @@ jQuery(async function () {
10882 if ($('.openDrawer').length !== 0) {10929 if ($('.openDrawer').length !== 0) {
10883 if (targetParentHasOpenDrawer === 0) {10930 if (targetParentHasOpenDrawer === 0) {
10884 //console.log($('.openDrawer').not('.pinnedOpen').length);10931 //console.log($('.openDrawer').not('.pinnedOpen').length);
10885 $('.openDrawer').not('.pinnedOpen').addClass('resizing').slideToggle(200, 'swing', function () {10932 $('.openDrawer').not('.pinnedOpen').addClass('resizing').each((_, el) => {
10886 $(this).closest('.drawer-content').removeClass('resizing');10933 slideToggle(el, {
10934 ...getSlideToggleOptions(),
10935 onAnimationEnd: (el) => {
10936 el.closest('.drawer-content').classList.remove('resizing');
10937 },
10938 });
10887 });10939 });
10888 $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon');10940 $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon');
10889 $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');10941 $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer');
10890
10891 }10942 }
10892 }10943 }
10893 }10944 }
@@ -11053,14 +11104,6 @@ jQuery(async function () {
11053 case 'renameCharButton':11104 case 'renameCharButton':
11054 renameCharacter();11105 renameCharacter();
11055 break;11106 break;
11056 /*case 'dupe_button':
11057 DupeChar();
11058 break;
11059 case 'export_button':
11060 $('#export_format_popup').toggle();
11061 exportPopper.update();
11062 break;
11063 */
11064 case 'import_character_info':11107 case 'import_character_info':
11065 await importEmbeddedWorldInfo();11108 await importEmbeddedWorldInfo();
11066 saveCharacterDebounced();11109 saveCharacterDebounced();
public/scripts/RossAscends-mods.js+8 -7
@@ -1,4 +1,4 @@
1import { DOMPurify, Bowser } from '../lib.js';1import { DOMPurify, Bowser, slideToggle } from '../lib.js';
22
3import {3import {
4 characters,4 characters,
@@ -19,6 +19,7 @@ import {
19 menu_type,19 menu_type,
20 substituteParams,20 substituteParams,
21 sendTextareaMessage,21 sendTextareaMessage,
22 getSlideToggleOptions,
22} from '../script.js';23} from '../script.js';
2324
24import {25import {
@@ -748,8 +749,8 @@ export function initRossMods() {
748 $(RightNavDrawerIcon).removeClass('drawerPinnedOpen');749 $(RightNavDrawerIcon).removeClass('drawerPinnedOpen');
749750
750 if ($(RightNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {751 if ($(RightNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {
751 $(RightNavPanel).slideToggle(200, 'swing');752 slideToggle(RightNavPanel, getSlideToggleOptions());
752 $(RightNavDrawerIcon).toggleClass('openIcon closedIcon');753 $(RightNavDrawerIcon).toggleClass('closedIcon openIcon');
753 $(RightNavPanel).toggleClass('openDrawer closedDrawer');754 $(RightNavPanel).toggleClass('openDrawer closedDrawer');
754 }755 }
755 }756 }
@@ -766,8 +767,8 @@ export function initRossMods() {
766 $(LeftNavDrawerIcon).removeClass('drawerPinnedOpen');767 $(LeftNavDrawerIcon).removeClass('drawerPinnedOpen');
767768
768 if ($(LeftNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {769 if ($(LeftNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) {
769 $(LeftNavPanel).slideToggle(200, 'swing');770 slideToggle(LeftNavPanel, getSlideToggleOptions());
770 $(LeftNavDrawerIcon).toggleClass('openIcon closedIcon');771 $(LeftNavDrawerIcon).toggleClass('closedIcon openIcon');
771 $(LeftNavPanel).toggleClass('openDrawer closedDrawer');772 $(LeftNavPanel).toggleClass('openDrawer closedDrawer');
772 }773 }
773 }774 }
@@ -786,8 +787,8 @@ export function initRossMods() {
786787
787 if ($(WorldInfo).hasClass('openDrawer') && $('.openDrawer').length > 1) {788 if ($(WorldInfo).hasClass('openDrawer') && $('.openDrawer').length > 1) {
788 console.debug('closing WI after lock removal');789 console.debug('closing WI after lock removal');
789 $(WorldInfo).slideToggle(200, 'swing');790 slideToggle(WorldInfo, getSlideToggleOptions());
790 $(WIDrawerIcon).toggleClass('openIcon closedIcon');791 $(WIDrawerIcon).toggleClass('closedIcon openIcon');
791 $(WorldInfo).toggleClass('openDrawer closedDrawer');792 $(WorldInfo).toggleClass('openDrawer closedDrawer');
792 }793 }
793 }794 }
public/scripts/extensions.js+8 -4
@@ -417,26 +417,30 @@ async function addExtensionsButtonAndMenu() {
417417
418 const button = $('#extensionsMenuButton');418 const button = $('#extensionsMenuButton');
419 const dropdown = $('#extensionsMenu');419 const dropdown = $('#extensionsMenu');
420 //dropdown.hide();420 let isDropdownVisible = false;
421421
422 let popper = Popper.createPopper(button.get(0), dropdown.get(0), {422 let popper = Popper.createPopper(button.get(0), dropdown.get(0), {
423 placement: 'top-start',423 placement: 'top-start',
424 });424 });
425425
426 $(button).on('click', function () {426 $(button).on('click', function () {
427 if (dropdown.is(':visible')) {427 if (isDropdownVisible) {
428 dropdown.fadeOut(animation_duration);428 dropdown.fadeOut(animation_duration);
429 isDropdownVisible = false;
429 } else {430 } else {
430 dropdown.fadeIn(animation_duration);431 dropdown.fadeIn(animation_duration);
432 isDropdownVisible = true;
431 }433 }
432 popper.update();434 popper.update();
433 });435 });
434436
435 $('html').on('click', function (e) {437 $('html').on('click', function (e) {
438 if (!isDropdownVisible) return;
436 const clickTarget = $(e.target);439 const clickTarget = $(e.target);
437 const noCloseTargets = ['#sd_gen', '#extensionsMenuButton', '#roll_dice'];440 const noCloseTargets = ['#sd_gen', '#extensionsMenuButton', '#roll_dice'];
438 if (dropdown.is(':visible') && !noCloseTargets.some(id => clickTarget.closest(id).length > 0)) {441 if (!noCloseTargets.some(id => clickTarget.closest(id).length > 0)) {
439 $(dropdown).fadeOut(animation_duration);442 dropdown.fadeOut(animation_duration);
443 isDropdownVisible = false;
440 }444 }
441 });445 });
442}446}
public/scripts/extensions/caption/index.js+1 -1
@@ -393,7 +393,7 @@ jQuery(async function () {
393 const sendButton = $(`393 const sendButton = $(`
394 <div id="send_picture" class="list-group-item flex-container flexGap5">394 <div id="send_picture" class="list-group-item flex-container flexGap5">
395 <div class="fa-solid fa-image extensionsMenuExtensionButton"></div>395 <div class="fa-solid fa-image extensionsMenuExtensionButton"></div>
396 Generate Caption396 <span data-i18n="Generate Caption">Generate Caption</span>
397 </div>`);397 </div>`);
398398
399 $('#caption_wand_container').append(sendButton);399 $('#caption_wand_container').append(sendButton);
public/scripts/extensions/caption/settings.html+0 -1
@@ -70,7 +70,6 @@
70 <option data-type="google" value="gemini-1.5-pro-002">gemini-1.5-pro-002</option>70 <option data-type="google" value="gemini-1.5-pro-002">gemini-1.5-pro-002</option>
71 <option data-type="google" value="gemini-1.5-pro-exp-0801">gemini-1.5-pro-exp-0801</option>71 <option data-type="google" value="gemini-1.5-pro-exp-0801">gemini-1.5-pro-exp-0801</option>
72 <option data-type="google" value="gemini-1.5-pro-exp-0827">gemini-1.5-pro-exp-0827</option>72 <option data-type="google" value="gemini-1.5-pro-exp-0827">gemini-1.5-pro-exp-0827</option>
73 <option data-type="google" value="gemini-pro-vision">gemini-pro-vision</option>
74 <option data-type="groq" value="llama-3.2-11b-vision-preview">llama-3.2-11b-vision-preview</option>73 <option data-type="groq" value="llama-3.2-11b-vision-preview">llama-3.2-11b-vision-preview</option>
75 <option data-type="groq" value="llama-3.2-90b-vision-preview">llama-3.2-90b-vision-preview</option>74 <option data-type="groq" value="llama-3.2-90b-vision-preview">llama-3.2-90b-vision-preview</option>
76 <option data-type="groq" value="llava-v1.5-7b-4096-preview">llava-v1.5-7b-4096-preview</option>75 <option data-type="groq" value="llava-v1.5-7b-4096-preview">llava-v1.5-7b-4096-preview</option>
public/scripts/extensions/stable-diffusion/button.html+2 -2
@@ -1,8 +1,8 @@
1<div id="sd_gen" class="list-group-item flex-container flexGap5">1<div id="sd_gen" class="list-group-item flex-container flexGap5">
2 <div class="fa-solid fa-paintbrush extensionsMenuExtensionButton" title="Trigger Stable Diffusion" data-i18n="[title]Trigger Stable Diffusion"></div>2 <div class="fa-solid fa-paintbrush extensionsMenuExtensionButton" title="Trigger Stable Diffusion" data-i18n="[title]Trigger Stable Diffusion"></div>
3 <span>Generate Image</span>3 <span data-i18n="Generate Image">Generate Image</span>
4</div>4</div>
5<div id="sd_stop_gen" class="list-group-item flex-container flexGap5">5<div id="sd_stop_gen" class="list-group-item flex-container flexGap5">
6 <div class="fa-solid fa-circle-stop extensionsMenuExtensionButton" title="Abort current image generation task" data-i18n="[title]Abort current image generation task"></div>6 <div class="fa-solid fa-circle-stop extensionsMenuExtensionButton" title="Abort current image generation task" data-i18n="[title]Abort current image generation task"></div>
7 <span>Stop Image Generation</span>7 <span data-i18n="Stop Image Generation">Stop Image Generation</span>
8</div>8</div>
public/scripts/extensions/stable-diffusion/index.js+10 -0
@@ -319,6 +319,7 @@ const defaultSettings = {
319 wand_visible: false,319 wand_visible: false,
320 command_visible: false,320 command_visible: false,
321 interactive_visible: false,321 interactive_visible: false,
322 tool_visible: false,
322323
323 // Stability AI settings324 // Stability AI settings
324 stability_style_preset: 'anime',325 stability_style_preset: 'anime',
@@ -488,6 +489,7 @@ async function loadSettings() {
488 $('#sd_wand_visible').prop('checked', extension_settings.sd.wand_visible);489 $('#sd_wand_visible').prop('checked', extension_settings.sd.wand_visible);
489 $('#sd_command_visible').prop('checked', extension_settings.sd.command_visible);490 $('#sd_command_visible').prop('checked', extension_settings.sd.command_visible);
490 $('#sd_interactive_visible').prop('checked', extension_settings.sd.interactive_visible);491 $('#sd_interactive_visible').prop('checked', extension_settings.sd.interactive_visible);
492 $('#sd_tool_visible').prop('checked', extension_settings.sd.tool_visible);
491 $('#sd_stability_style_preset').val(extension_settings.sd.stability_style_preset);493 $('#sd_stability_style_preset').val(extension_settings.sd.stability_style_preset);
492 $('#sd_huggingface_model_id').val(extension_settings.sd.huggingface_model_id);494 $('#sd_huggingface_model_id').val(extension_settings.sd.huggingface_model_id);
493 $('#sd_function_tool').prop('checked', extension_settings.sd.function_tool);495 $('#sd_function_tool').prop('checked', extension_settings.sd.function_tool);
@@ -844,6 +846,11 @@ function onInteractiveVisibleInput() {
844 saveSettingsDebounced();846 saveSettingsDebounced();
845}847}
846848
849function onToolVisibleInput() {
850 extension_settings.sd.tool_visible = !!$('#sd_tool_visible').prop('checked');
851 saveSettingsDebounced();
852}
853
847function onClipSkipInput() {854function onClipSkipInput() {
848 extension_settings.sd.clip_skip = Number($('#sd_clip_skip').val());855 extension_settings.sd.clip_skip = Number($('#sd_clip_skip').val());
849 $('#sd_clip_skip_value').val(extension_settings.sd.clip_skip);856 $('#sd_clip_skip_value').val(extension_settings.sd.clip_skip);
@@ -3670,6 +3677,8 @@ function getVisibilityByInitiator(initiator) {
3670 return !!extension_settings.sd.wand_visible;3677 return !!extension_settings.sd.wand_visible;
3671 case initiators.command:3678 case initiators.command:
3672 return !!extension_settings.sd.command_visible;3679 return !!extension_settings.sd.command_visible;
3680 case initiators.tool:
3681 return !!extension_settings.sd.tool_visible;
3673 default:3682 default:
3674 return false;3683 return false;
3675 }3684 }
@@ -4417,6 +4426,7 @@ jQuery(async () => {
4417 $('#sd_wand_visible').on('input', onWandVisibleInput);4426 $('#sd_wand_visible').on('input', onWandVisibleInput);
4418 $('#sd_command_visible').on('input', onCommandVisibleInput);4427 $('#sd_command_visible').on('input', onCommandVisibleInput);
4419 $('#sd_interactive_visible').on('input', onInteractiveVisibleInput);4428 $('#sd_interactive_visible').on('input', onInteractiveVisibleInput);
4429 $('#sd_tool_visible').on('input', onToolVisibleInput);
4420 $('#sd_swap_dimensions').on('click', onSwapDimensionsClick);4430 $('#sd_swap_dimensions').on('click', onSwapDimensionsClick);
4421 $('#sd_stability_key').on('click', onStabilityKeyClick);4431 $('#sd_stability_key').on('click', onStabilityKeyClick);
4422 $('#sd_stability_style_preset').on('change', onStabilityStylePresetChange);4432 $('#sd_stability_style_preset').on('change', onStabilityStylePresetChange);
public/scripts/extensions/stable-diffusion/settings.html+10 -3
@@ -459,25 +459,32 @@
459 <div class="flex-container flexFlowColumn marginTopBot5 flexGap10">459 <div class="flex-container flexFlowColumn marginTopBot5 flexGap10">
460 <label for="sd_wand_visible" class="checkbox_label">460 <label for="sd_wand_visible" class="checkbox_label">
461 <span class="flex1 flex-container alignItemsCenter">461 <span class="flex1 flex-container alignItemsCenter">
462 <i class="fa-solid fa-wand-magic-sparkles"></i>462 <i class="fa-solid fa-wand-magic-sparkles fa-fw"></i>
463 <span data-i18n="Extensions Menu">Extensions Menu</span>463 <span data-i18n="Extensions Menu">Extensions Menu</span>
464 </span>464 </span>
465 <input id="sd_wand_visible" type="checkbox" />465 <input id="sd_wand_visible" type="checkbox" />
466 </label>466 </label>
467 <label for="sd_command_visible" class="checkbox_label">467 <label for="sd_command_visible" class="checkbox_label">
468 <span class="flex1 flex-container alignItemsCenter">468 <span class="flex1 flex-container alignItemsCenter">
469 <i class="fa-solid fa-terminal"></i>469 <i class="fa-solid fa-terminal fa-fw"></i>
470 <span data-i18n="Slash Command">Slash Command</span>470 <span data-i18n="Slash Command">Slash Command</span>
471 </span>471 </span>
472 <input id="sd_command_visible" type="checkbox" />472 <input id="sd_command_visible" type="checkbox" />
473 </label>473 </label>
474 <label for="sd_interactive_visible" class="checkbox_label">474 <label for="sd_interactive_visible" class="checkbox_label">
475 <span class="flex1 flex-container alignItemsCenter">475 <span class="flex1 flex-container alignItemsCenter">
476 <i class="fa-solid fa-message"></i>476 <i class="fa-solid fa-message fa-fw"></i>
477 <span data-i18n="Interactive Mode">Interactive Mode</span>477 <span data-i18n="Interactive Mode">Interactive Mode</span>
478 </span>478 </span>
479 <input id="sd_interactive_visible" type="checkbox" />479 <input id="sd_interactive_visible" type="checkbox" />
480 </label>480 </label>
481 <label for="sd_tool_visible" class="checkbox_label">
482 <span class="flex1 flex-container alignItemsCenter">
483 <i class="fa-solid fa-code fa-fw"></i>
484 <span data-i18n="Function Tool">Function Tool</span>
485 </span>
486 <input id="sd_tool_visible" type="checkbox" />
487 </label>
481 </div>488 </div>
482 </div>489 </div>
483 </div>490 </div>
public/scripts/macros.js+4 -0
@@ -516,7 +516,11 @@ export function evaluateMacros(content, env, postProcessFn) {
516 break;516 break;
517 }517 }
518518
519 try {
519 content = content.replace(macro.regex, (...args) => postProcessFn(macro.replace(...args)));520 content = content.replace(macro.regex, (...args) => postProcessFn(macro.replace(...args)));
521 } catch (e) {
522 console.warn(`Macro content can't be replaced: ${macro.regex} in ${content}`, e);
523 }
520 }524 }
521525
522 return content;526 return content;
public/scripts/openai.js+3 -12
@@ -4098,13 +4098,8 @@ async function onModelChange() {
4098 $('#openai_max_context').attr('max', max_2mil);4098 $('#openai_max_context').attr('max', max_2mil);
4099 } else if (value.includes('gemini-1.5-flash') || value.includes('gemini-2.0-flash-exp')) {4099 } else if (value.includes('gemini-1.5-flash') || value.includes('gemini-2.0-flash-exp')) {
4100 $('#openai_max_context').attr('max', max_1mil);4100 $('#openai_max_context').attr('max', max_1mil);
4101 } else if (value.includes('gemini-1.0-pro-vision') || value === 'gemini-pro-vision') {
4102 $('#openai_max_context').attr('max', max_16k);
4103 } else if (value.includes('gemini-1.0-pro') || value === 'gemini-pro') {4101 } else if (value.includes('gemini-1.0-pro') || value === 'gemini-pro') {
4104 $('#openai_max_context').attr('max', max_32k);4102 $('#openai_max_context').attr('max', max_32k);
4105 } else if (value === 'text-bison-001') {
4106 $('#openai_max_context').attr('max', max_8k);
4107 // The ultra endpoints are possibly dead:
4108 } else if (value.includes('gemini-1.0-ultra') || value === 'gemini-ultra') {4103 } else if (value.includes('gemini-1.0-ultra') || value === 'gemini-ultra') {
4109 $('#openai_max_context').attr('max', max_32k);4104 $('#openai_max_context').attr('max', max_32k);
4110 } else {4105 } else {
@@ -4226,16 +4221,13 @@ async function onModelChange() {
4226 if (oai_settings.max_context_unlocked) {4221 if (oai_settings.max_context_unlocked) {
4227 $('#openai_max_context').attr('max', unlocked_max);4222 $('#openai_max_context').attr('max', unlocked_max);
4228 }4223 }
4229 else if (['command-light', 'command'].includes(oai_settings.cohere_model)) {4224 else if (['command-light-nightly', 'command-light', 'command'].includes(oai_settings.cohere_model)) {
4230 $('#openai_max_context').attr('max', max_4k);4225 $('#openai_max_context').attr('max', max_4k);
4231 }4226 }
4232 else if (['command-light-nightly', 'command-nightly'].includes(oai_settings.cohere_model)) {4227 else if (oai_settings.cohere_model.includes('command-r') || ['c4ai-aya-23', 'c4ai-aya-expanse-32b', 'command-nightly'].includes(oai_settings.cohere_model)) {
4233 $('#openai_max_context').attr('max', max_8k);
4234 }
4235 else if (oai_settings.cohere_model.includes('command-r') || ['c4ai-aya-expanse-32b'].includes(oai_settings.cohere_model)) {
4236 $('#openai_max_context').attr('max', max_128k);4228 $('#openai_max_context').attr('max', max_128k);
4237 }4229 }
4238 else if (['c4ai-aya-23', 'c4ai-aya-expanse-8b'].includes(oai_settings.cohere_model)) {4230 else if (['c4ai-aya-23-8b', 'c4ai-aya-expanse-8b'].includes(oai_settings.cohere_model)) {
4239 $('#openai_max_context').attr('max', max_8k);4231 $('#openai_max_context').attr('max', max_8k);
4240 }4232 }
4241 else {4233 else {
@@ -4787,7 +4779,6 @@ export function isImageInliningSupported() {
4787 'gemini-1.5-pro-002',4779 'gemini-1.5-pro-002',
4788 'gemini-1.5-pro-exp-0801',4780 'gemini-1.5-pro-exp-0801',
4789 'gemini-1.5-pro-exp-0827',4781 'gemini-1.5-pro-exp-0827',
4790 'gemini-pro-vision',
4791 'claude-3',4782 'claude-3',
4792 'claude-3-5',4783 'claude-3-5',
4793 'gpt-4-turbo',4784 'gpt-4-turbo',
public/scripts/textgen-settings.js+5 -2
@@ -55,6 +55,7 @@ const {
55} = textgen_types;55} = textgen_types;
5656
57const LLAMACPP_DEFAULT_ORDER = [57const LLAMACPP_DEFAULT_ORDER = [
58 'dry',
58 'top_k',59 'top_k',
59 'tfs_z',60 'tfs_z',
60 'typical_p',61 'typical_p',
@@ -1038,11 +1039,13 @@ export function parseTextgenLogprobs(token, logprobs) {
1038 return { token, topLogprobs: candidates };1039 return { token, topLogprobs: candidates };
1039 }1040 }
1040 case LLAMACPP: {1041 case LLAMACPP: {
1041 /** @type {Record<string, number>[]} */
1042 if (!logprobs?.length) {1042 if (!logprobs?.length) {
1043 return null;1043 return null;
1044 }1044 }
1045 const candidates = logprobs[0].probs.map(x => [x.tok_str, x.prob]);1045 const candidates = logprobs?.[0]?.probs?.map(x => [x.tok_str, x.prob]);
1046 if (!candidates) {
1047 return null;
1048 }
1046 return { token, topLogprobs: candidates };1049 return { token, topLogprobs: candidates };
1047 }1050 }
1048 default:1051 default:
public/scripts/tool-calling.js+58 -5
@@ -25,6 +25,7 @@ import { isTrueBoolean } from './utils.js';
25 * @typedef {object} ToolInvocationResult25 * @typedef {object} ToolInvocationResult
26 * @property {ToolInvocation[]} invocations Successful tool invocations26 * @property {ToolInvocation[]} invocations Successful tool invocations
27 * @property {Error[]} errors Errors that occurred during tool invocation27 * @property {Error[]} errors Errors that occurred during tool invocation
28 * @property {string[]} stealthCalls Names of stealth tools that were invoked
28 */29 */
2930
30/**31/**
@@ -36,6 +37,7 @@ import { isTrueBoolean } from './utils.js';
36 * @property {function} action - The action to perform when the tool is invoked.37 * @property {function} action - The action to perform when the tool is invoked.
37 * @property {function} [formatMessage] - A function to format the tool call message.38 * @property {function} [formatMessage] - A function to format the tool call message.
38 * @property {function} [shouldRegister] - A function to determine if the tool should be registered.39 * @property {function} [shouldRegister] - A function to determine if the tool should be registered.
40 * @property {boolean} [stealth] - A tool call result will not be shown in the chat. No follow-up generation will be performed.
39 */41 */
4042
41/**43/**
@@ -148,6 +150,12 @@ class ToolDefinition {
148 #shouldRegister;150 #shouldRegister;
149151
150 /**152 /**
153 * A tool call result will not be shown in the chat. No follow-up generation will be performed.
154 * @type {boolean}
155 */
156 #stealth;
157
158 /**
151 * Creates a new ToolDefinition.159 * Creates a new ToolDefinition.
152 * @param {string} name A unique name for the tool.160 * @param {string} name A unique name for the tool.
153 * @param {string} displayName A user-friendly display name for the tool.161 * @param {string} displayName A user-friendly display name for the tool.
@@ -156,8 +164,9 @@ class ToolDefinition {
156 * @param {function} action A function that will be called when the tool is executed.164 * @param {function} action A function that will be called when the tool is executed.
157 * @param {function} formatMessage A function that will be called to format the tool call toast.165 * @param {function} formatMessage A function that will be called to format the tool call toast.
158 * @param {function} shouldRegister A function that will be called to determine if the tool should be registered.166 * @param {function} shouldRegister A function that will be called to determine if the tool should be registered.
167 * @param {boolean} stealth A tool call result will not be shown in the chat. No follow-up generation will be performed.
159 */168 */
160 constructor(name, displayName, description, parameters, action, formatMessage, shouldRegister) {169 constructor(name, displayName, description, parameters, action, formatMessage, shouldRegister, stealth) {
161 this.#name = name;170 this.#name = name;
162 this.#displayName = displayName;171 this.#displayName = displayName;
163 this.#description = description;172 this.#description = description;
@@ -165,6 +174,7 @@ class ToolDefinition {
165 this.#action = action;174 this.#action = action;
166 this.#formatMessage = formatMessage;175 this.#formatMessage = formatMessage;
167 this.#shouldRegister = shouldRegister;176 this.#shouldRegister = shouldRegister;
177 this.#stealth = stealth;
168 }178 }
169179
170 /**180 /**
@@ -214,6 +224,10 @@ class ToolDefinition {
214 get displayName() {224 get displayName() {
215 return this.#displayName;225 return this.#displayName;
216 }226 }
227
228 get stealth() {
229 return this.#stealth;
230 }
217}231}
218232
219/**233/**
@@ -246,7 +260,7 @@ export class ToolManager {
246 * Registers a new tool with the tool registry.260 * Registers a new tool with the tool registry.
247 * @param {ToolRegistration} tool The tool to register.261 * @param {ToolRegistration} tool The tool to register.
248 */262 */
249 static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage, shouldRegister }) {263 static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage, shouldRegister, stealth }) {
250 // Convert WIP arguments264 // Convert WIP arguments
251 if (typeof arguments[0] !== 'object') {265 if (typeof arguments[0] !== 'object') {
252 [name, description, parameters, action] = arguments;266 [name, description, parameters, action] = arguments;
@@ -256,7 +270,16 @@ export class ToolManager {
256 console.warn(`[ToolManager] A tool with the name "${name}" has already been registered. The definition will be overwritten.`);270 console.warn(`[ToolManager] A tool with the name "${name}" has already been registered. The definition will be overwritten.`);
257 }271 }
258272
259 const definition = new ToolDefinition(name, displayName, description, parameters, action, formatMessage, shouldRegister);273 const definition = new ToolDefinition(
274 name,
275 displayName,
276 description,
277 parameters,
278 action,
279 formatMessage,
280 shouldRegister,
281 stealth,
282 );
260 this.#tools.set(name, definition);283 this.#tools.set(name, definition);
261 console.log('[ToolManager] Registered function tool:', definition);284 console.log('[ToolManager] Registered function tool:', definition);
262 }285 }
@@ -303,6 +326,20 @@ export class ToolManager {
303 }326 }
304327
305 /**328 /**
329 * Checks if a tool is a stealth tool.
330 * @param {string} name The name of the tool to check.
331 * @returns {boolean} Whether the tool is a stealth tool.
332 */
333 static isStealthTool(name) {
334 if (!this.#tools.has(name)) {
335 return false;
336 }
337
338 const tool = this.#tools.get(name);
339 return !!tool.stealth;
340 }
341
342 /**
306 * Formats a message for a tool call by name.343 * Formats a message for a tool call by name.
307 * @param {string} name The name of the tool to format the message for.344 * @param {string} name The name of the tool to format the message for.
308 * @param {object} parameters Function tool call parameters.345 * @param {object} parameters Function tool call parameters.
@@ -608,6 +645,7 @@ export class ToolManager {
608 const result = {645 const result = {
609 invocations: [],646 invocations: [],
610 errors: [],647 errors: [],
648 stealthCalls: [],
611 };649 };
612 const toolCalls = ToolManager.#getToolCallsFromData(data);650 const toolCalls = ToolManager.#getToolCallsFromData(data);
613651
@@ -625,7 +663,7 @@ export class ToolManager {
625 const parameters = toolCall.function.arguments;663 const parameters = toolCall.function.arguments;
626 const name = toolCall.function.name;664 const name = toolCall.function.name;
627 const displayName = ToolManager.getDisplayName(name);665 const displayName = ToolManager.getDisplayName(name);
628666 const isStealth = ToolManager.isStealthTool(name);
629 const message = await ToolManager.formatToolCallMessage(name, parameters);667 const message = await ToolManager.formatToolCallMessage(name, parameters);
630 const toast = message && toastr.info(message, 'Tool Calling', { timeOut: 0 });668 const toast = message && toastr.info(message, 'Tool Calling', { timeOut: 0 });
631 const toolResult = await ToolManager.invokeFunctionTool(name, parameters);669 const toolResult = await ToolManager.invokeFunctionTool(name, parameters);
@@ -638,6 +676,12 @@ export class ToolManager {
638 continue;676 continue;
639 }677 }
640678
679 // Don't save stealth tool invocations
680 if (isStealth) {
681 result.stealthCalls.push(name);
682 continue;
683 }
684
641 const invocation = {685 const invocation = {
642 id,686 id,
643 displayName,687 displayName,
@@ -860,6 +904,14 @@ export class ToolManager {
860 isRequired: false,904 isRequired: false,
861 acceptsMultiple: false,905 acceptsMultiple: false,
862 }),906 }),
907 SlashCommandNamedArgument.fromProps({
908 name: 'stealth',
909 description: 'If true, a tool call result will not be shown in the chat and no follow-up generation will be performed.',
910 typeList: [ARGUMENT_TYPE.BOOLEAN],
911 isRequired: false,
912 acceptsMultiple: false,
913 defaultValue: String(false),
914 }),
863 ],915 ],
864 unnamedArgumentList: [916 unnamedArgumentList: [
865 SlashCommandArgument.fromProps({917 SlashCommandArgument.fromProps({
@@ -891,7 +943,7 @@ export class ToolManager {
891 };943 };
892 }944 }
893945
894 const { name, displayName, description, parameters, formatMessage, shouldRegister } = args;946 const { name, displayName, description, parameters, formatMessage, shouldRegister, stealth } = args;
895947
896 if (!(action instanceof SlashCommandClosure)) {948 if (!(action instanceof SlashCommandClosure)) {
897 throw new Error('The unnamed argument must be a closure.');949 throw new Error('The unnamed argument must be a closure.');
@@ -927,6 +979,7 @@ export class ToolManager {
927 action: actionFunc,979 action: actionFunc,
928 formatMessage: formatMessageFunc,980 formatMessage: formatMessageFunc,
929 shouldRegister: shouldRegisterFunc,981 shouldRegister: shouldRegisterFunc,
982 stealth: stealth && isTrueBoolean(String(stealth)),
930 });983 });
931984
932 return '';985 return '';
public/scripts/variables.js+8 -0
@@ -46,6 +46,10 @@ function getLocalVariable(name, args = {}) {
46}46}
4747
48function setLocalVariable(name, value, args = {}) {48function setLocalVariable(name, value, args = {}) {
49 if (!name) {
50 throw new Error('Variable name cannot be empty or undefined.');
51 }
52
49 if (!chat_metadata.variables) {53 if (!chat_metadata.variables) {
50 chat_metadata.variables = {};54 chat_metadata.variables = {};
51 }55 }
@@ -99,6 +103,10 @@ function getGlobalVariable(name, args = {}) {
99}103}
100104
101function setGlobalVariable(name, value, args = {}) {105function setGlobalVariable(name, value, args = {}) {
106 if (!name) {
107 throw new Error('Variable name cannot be empty or undefined.');
108 }
109
102 if (args.index !== undefined) {110 if (args.index !== undefined) {
103 try {111 try {
104 let globalVariable = JSON.parse(extension_settings.variables.global[name] ?? 'null');112 let globalVariable = JSON.parse(extension_settings.variables.global[name] ?? 'null');
public/style.css+2 -1
@@ -2874,6 +2874,7 @@ input[type=search]:focus::-webkit-search-cancel-button {
28742874
2875.mes_block .ch_name {2875.mes_block .ch_name {
2876 max-width: 100%;2876 max-width: 100%;
2877 min-height: 22px;
2877}2878}
28782879
2879/*applies to both groups and solos chars in the char list*/2880/*applies to both groups and solos chars in the char list*/
@@ -4043,7 +4044,7 @@ input[type="range"]::-webkit-slider-thumb {
4043.mes_button,4044.mes_button,
4044.extraMesButtons>div {4045.extraMesButtons>div {
4045 cursor: pointer;4046 cursor: pointer;
4046 transition: 0.3s ease-in-out;4047 transition: opacity 0.2s ease-in-out;
4047 filter: drop-shadow(0px 0px 2px black);4048 filter: drop-shadow(0px 0px 2px black);
4048 opacity: 0.3;4049 opacity: 0.3;
4049 padding: 1px 3px;4050 padding: 1px 3px;
src/constants.js+0 -27
@@ -159,33 +159,6 @@ export const GEMINI_SAFETY = [
159 },159 },
160];160];
161161
162export const BISON_SAFETY = [
163 {
164 category: 'HARM_CATEGORY_DEROGATORY',
165 threshold: 'BLOCK_NONE',
166 },
167 {
168 category: 'HARM_CATEGORY_TOXICITY',
169 threshold: 'BLOCK_NONE',
170 },
171 {
172 category: 'HARM_CATEGORY_VIOLENCE',
173 threshold: 'BLOCK_NONE',
174 },
175 {
176 category: 'HARM_CATEGORY_SEXUAL',
177 threshold: 'BLOCK_NONE',
178 },
179 {
180 category: 'HARM_CATEGORY_MEDICAL',
181 threshold: 'BLOCK_NONE',
182 },
183 {
184 category: 'HARM_CATEGORY_DANGEROUS',
185 threshold: 'BLOCK_NONE',
186 },
187];
188
189export const CHAT_COMPLETION_SOURCES = {162export const CHAT_COMPLETION_SOURCES = {
190 OPENAI: 'openai',163 OPENAI: 'openai',
191 WINDOWAI: 'windowai',164 WINDOWAI: 'windowai',
src/endpoints/backends/chat-completions.js+5 -42
@@ -6,7 +6,6 @@ import { jsonParser } from '../../express-common.js';
6import {6import {
7 CHAT_COMPLETION_SOURCES,7 CHAT_COMPLETION_SOURCES,
8 GEMINI_SAFETY,8 GEMINI_SAFETY,
9 BISON_SAFETY,
10 OPENROUTER_HEADERS,9 OPENROUTER_HEADERS,
11} from '../../constants.js';10} from '../../constants.js';
12import {11import {
@@ -262,9 +261,7 @@ async function sendMakerSuiteRequest(request, response) {
262 }261 }
263262
264 const model = String(request.body.model);263 const model = String(request.body.model);
265 const isGemini = model.includes('gemini');264 const stream = Boolean(request.body.stream);
266 const isText = model.includes('text');
267 const stream = Boolean(request.body.stream) && isGemini;
268265
269 const generationConfig = {266 const generationConfig = {
270 stopSequences: request.body.stop,267 stopSequences: request.body.stop,
@@ -301,39 +298,7 @@ async function sendMakerSuiteRequest(request, response) {
301 return body;298 return body;
302 }299 }
303300
304 function getBisonBody() {301 const body = getGeminiBody();
305 const prompt = isText
306 ? ({ text: convertTextCompletionPrompt(request.body.messages) })
307 : ({ messages: convertGooglePrompt(request.body.messages, model).contents });
308
309 /** @type {any} Shut the lint up */
310 const bisonBody = {
311 ...generationConfig,
312 safetySettings: BISON_SAFETY,
313 candidate_count: 1, // lewgacy spelling
314 prompt: prompt,
315 };
316
317 if (!isText) {
318 delete bisonBody.stopSequences;
319 delete bisonBody.maxOutputTokens;
320 delete bisonBody.safetySettings;
321
322 if (Array.isArray(prompt.messages)) {
323 for (const msg of prompt.messages) {
324 msg.author = msg.role;
325 msg.content = msg.parts[0].text;
326 delete msg.parts;
327 delete msg.role;
328 }
329 }
330 }
331
332 delete bisonBody.candidateCount;
333 return bisonBody;
334 }
335
336 const body = isGemini ? getGeminiBody() : getBisonBody();
337 console.log('Google AI Studio request:', body);302 console.log('Google AI Studio request:', body);
338303
339 try {304 try {
@@ -343,10 +308,8 @@ async function sendMakerSuiteRequest(request, response) {
343 controller.abort();308 controller.abort();
344 });309 });
345310
346 const apiVersion = isGemini ? 'v1beta' : 'v1beta2';311 const apiVersion = 'v1beta';
347 const responseType = isGemini312 const responseType = (stream ? 'streamGenerateContent' : 'generateContent');
348 ? (stream ? 'streamGenerateContent' : 'generateContent')
349 : (isText ? 'generateText' : 'generateMessage');
350313
351 const generateResponse = await fetch(`${apiUrl.toString().replace(/\/$/, '')}/${apiVersion}/models/${model}:${responseType}?key=${apiKey}${stream ? '&alt=sse' : ''}`, {314 const generateResponse = await fetch(`${apiUrl.toString().replace(/\/$/, '')}/${apiVersion}/models/${model}:${responseType}?key=${apiKey}${stream ? '&alt=sse' : ''}`, {
352 body: JSON.stringify(body),315 body: JSON.stringify(body),
@@ -897,7 +860,7 @@ router.post('/generate', jsonParser, function (request, response) {
897 }860 }
898861
899 let cachingAtDepth = getConfigValue('claude.cachingAtDepth', -1);862 let cachingAtDepth = getConfigValue('claude.cachingAtDepth', -1);
900 if (Number.isInteger(cachingAtDepth) && cachingAtDepth >= 0 && request.body.model.startsWith('anthropic/claude-3')) {863 if (Number.isInteger(cachingAtDepth) && cachingAtDepth >= 0 && request.body.model?.startsWith('anthropic/claude-3')) {
901 cachingAtDepthForOpenRouterClaude(request.body.messages, cachingAtDepth);864 cachingAtDepthForOpenRouterClaude(request.body.messages, cachingAtDepth);
902 }865 }
903 } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.CUSTOM) {866 } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.CUSTOM) {
src/prompt-converters.js+0 -19
@@ -333,8 +333,6 @@ export function convertCohereMessages(messages, charName = '', userName = '') {
333 * @returns {{contents: *[], system_instruction: {parts: {text: string}}}} Prompt for Google MakerSuite models333 * @returns {{contents: *[], system_instruction: {parts: {text: string}}}} Prompt for Google MakerSuite models
334 */334 */
335export function convertGooglePrompt(messages, model, useSysPrompt = false, charName = '', userName = '') {335export function convertGooglePrompt(messages, model, useSysPrompt = false, charName = '', userName = '') {
336 // This is a 1x1 transparent PNG
337 const PNG_PIXEL = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
338336
339 const visionSupportedModels = [337 const visionSupportedModels = [
340 'gemini-2.0-flash-exp',338 'gemini-2.0-flash-exp',
@@ -355,13 +353,6 @@ export function convertGooglePrompt(messages, model, useSysPrompt = false, charN
355 'gemini-1.5-pro-002',353 'gemini-1.5-pro-002',
356 'gemini-1.5-pro-exp-0801',354 'gemini-1.5-pro-exp-0801',
357 'gemini-1.5-pro-exp-0827',355 'gemini-1.5-pro-exp-0827',
358 'gemini-1.0-pro-vision-latest',
359 'gemini-pro-vision',
360 ];
361
362 const dummyRequiredModels = [
363 'gemini-1.0-pro-vision-latest',
364 'gemini-pro-vision',
365 ];356 ];
366357
367 const isMultimodal = visionSupportedModels.includes(model);358 const isMultimodal = visionSupportedModels.includes(model);
@@ -452,16 +443,6 @@ export function convertGooglePrompt(messages, model, useSysPrompt = false, charN
452 }443 }
453 });444 });
454445
455 // pro 1.5 doesn't require a dummy image to be attached, other vision models do
456 if (isMultimodal && dummyRequiredModels.includes(model) && !hasImage) {
457 contents[0].parts.push({
458 inlineData: {
459 mimeType: 'image/png',
460 data: PNG_PIXEL,
461 },
462 });
463 }
464
465 return { contents: contents, system_instruction: system_instruction };446 return { contents: contents, system_instruction: system_instruction };
466}447}
467448