Merge branch 'staging' into connection-manager

f4da527d95f817e0f5077a072e2e8254fa0137ba

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

3 files changed, +106 -37Showing whitespace changes
public/index.html+21 -12
@@ -1916,17 +1916,26 @@
19161916 <form action="javascript:void(null);" method="post" enctype="multipart/form-data">
19171917 <div id="kobold_horde_block">
19181918 <ul>
1919- <li data-i18n="Avoid sending sensitive information to the Horde.">
1919+ <li>
1920- Avoid sending sensitive information to the Horde.
1920+ <a target="_blank" href="https://aihorde.net/" data-i18n="KoboldAI Horde Website">
1921- <a target="_blank" href="https://docs.sillytavern.app/usage/api-connections/horde/" data-i18n="Review the Privacy statement">Review the Privacy statement</a>
1921+ KoboldAI Horde Website
1922+ </a>
1923+ </li>
1924+ <li>
1925+ <span data-i18n="Avoid sending sensitive information to the Horde.">Avoid sending sensitive information to the Horde.</span>
1926+ <a target="_blank" href="https://docs.sillytavern.app/usage/api-connections/horde/" data-i18n="Review the Privacy statement">
1927+ Review the Privacy statement
1928+ </a>
19221929 </li>
19231930 <li>
19241931 <a target="_blank" href="https://horde.koboldaiaihorde.net/register" data-i18n="Register a Horde account for faster queue times">Register a Horde
19251932 Register a Horde account for faster queue times</a>
1933+ </a>
19261934 </li>
19271935 <li>
19281936 <a target="_blank" href="https://github.com/Haidra-Org/horde-worker-reGen?tab=readme-ov-file#ai-horde-worker-regen" data-i18n="Learn how to contribute your idle GPU cycles to the Horde">Learn
19291937 Learn how to contribute your idle GPU cycles to the Horde</a>
1938+ </a>
19301939 </li>
19311940 </ul>
19321941 <label for="horde_auto_adjust_context_length" class="checkbox_label">
@@ -1944,12 +1953,9 @@
19441953 <small id="adjustedHordeParams">Context: --, Response: --</small>
19451954 <h4 data-i18n="API key">API key</h4>
19461955 <small>
19471956 <span data-i18n="Get it here:">Get it here: </span> <a target="_blank" href="https://horde.koboldaiaihorde.net/register" data-i18n="Register">Register</a> (<a id="horde_kudos" href="javascript:void(0);" data-i18n="View my Kudos">View my Kudos</a>)<br>
19481957 <span data-i18n="Enter">Enter </span> <span class="monospace">0000000000</span> <span data-i18n="to use anonymous mode.">to use anonymous mode. </span>
19491958 </small>
1950- <!-- <div>
1951- <a id="horde_kudos" href="javascript:void(0);">View my Kudos</a>
1952- </div> -->
19531959 <div class="flex-container">
19541960 <input id="horde_api_key" name="horde_api_key" class="text_pole flex1" type="text" placeholder="0000000000" autocomplete="off">
19551961 <div title="Clear your API key" data-i18n="[title]Clear your API key" class="menu_button fa-solid fa-circle-xmark clear-api-key" data-key="api_key_horde"></div>
@@ -4333,7 +4339,10 @@
43334339 </div>
43344340 <div id="Backgrounds" class="drawer-content closedDrawer">
43354341 <div class="flex-container">
43364342 <div class="flex-container alignItemsBaseline wide100p">
4343+ <h3 class="margin0 flex2" data-i18n="Background Image">
4344+ Background Image
4345+ </h3>
43374346 <input id="bg-filter" data-i18n="[placeholder]Filter" placeholder="Filter" class="text_pole flex1" type="search" />
43384347 <div id="auto_background" class="menu_button menu_button_icon" data-i18n="[title]Automatically select a background based on the chat context" title="Automatically select a background based on the chat context.">
43394348 <i class="fa-solid fa-wand-magic"></i>
public/scripts/popup.js+2 -2
@@ -92,7 +92,7 @@ const showPopupHelper = {
9292 * @param {string?} header - The header text for the popup.
9393 * @param {string?} text - The main text for the popup.
9494 * @param {PopupOptions} [popupOptions={}] - Options for the popup.
9595 * @return {Promise<POPUP_RESULT?>} A Promise that resolves with the result of the user's interaction.
9696 */
9797 confirm: async (header, text, popupOptions = {}) => {
9898 const content = PopupUtils.BuildTextWithHeader(header, text);
@@ -107,7 +107,7 @@ const showPopupHelper = {
107107 * @param {string?} header - The header text for the popup.
108108 * @param {string?} text - The main text for the popup.
109109 * @param {PopupOptions} [popupOptions={}] - Options for the popup.
110110 * @return {Promise<POPUP_RESULT?>} A Promise that resolves with the result of the user's interaction.
111111 */
112112 text: async (header, text, popupOptions = {}) => {
113113 const content = PopupUtils.BuildTextWithHeader(header, text);
public/scripts/slash-commands.js+83 -23
@@ -1267,20 +1267,59 @@ export function initDefaultSlashCommands() {
12671267 callback: popupCallback,
12681268 returns: 'popup text',
12691269 namedArgumentList: [
12701270 new SlashCommandNamedArgument.fromProps({
1271- 'large', 'show large popup', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(),
1271+ name: 'large',
1272- ),
1272+ description: 'show large popup',
1273- new SlashCommandNamedArgument(
1273+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1274- 'wide', 'show wide popup', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(),
1274+ enumList: commonEnumProviders.boolean('trueFalse')(),
1275- ),
1275+ defaultValue: 'false',
1276- new SlashCommandNamedArgument(
1276+ }),
1277- 'okButton', 'text for the OK button', [ARGUMENT_TYPE.STRING], false,
1277+ SlashCommandNamedArgument.fromProps({
1278- ),
1278+ name: 'wide',
1279+ description: 'show wide popup',
1280+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1281+ enumList: commonEnumProviders.boolean('trueFalse')(),
1282+ defaultValue: 'false',
1283+ }),
1284+ SlashCommandNamedArgument.fromProps({
1285+ name: 'wider',
1286+ description: 'show wider popup',
1287+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1288+ enumList: commonEnumProviders.boolean('trueFalse')(),
1289+ defaultValue: 'false',
1290+ }),
1291+ SlashCommandNamedArgument.fromProps({
1292+ name: 'transparent',
1293+ description: 'show transparent popup',
1294+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1295+ enumList: commonEnumProviders.boolean('trueFalse')(),
1296+ defaultValue: 'false',
1297+ }),
1298+ SlashCommandNamedArgument.fromProps({
1299+ name: 'okButton',
1300+ description: 'text for the OK button',
1301+ typeList: [ARGUMENT_TYPE.STRING],
1302+ defaultValue: 'OK',
1303+ }),
1304+ SlashCommandNamedArgument.fromProps({
1305+ name: 'cancelButton',
1306+ description: 'text for the Cancel button',
1307+ typeList: [ARGUMENT_TYPE.STRING],
1308+ }),
1309+ SlashCommandNamedArgument.fromProps({
1310+ name: 'result',
1311+ description: 'if enabled, returns the popup result (as an integer) instead of the popup text. Resolves to 1 for OK and 0 cancel button, empty string for exiting out.',
1312+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1313+ enumList: commonEnumProviders.boolean('trueFalse')(),
1314+ defaultValue: 'false',
1315+ }),
12791316 ],
12801317 unnamedArgumentList: [
12811318 new SlashCommandArgument.fromProps({
1282- 'text', [ARGUMENT_TYPE.STRING], true,
1319+ description: 'popup text',
1283- ),
1320+ typeList: [ARGUMENT_TYPE.STRING],
1321+ isRequired: true,
1322+ }),
12841323 ],
12851324 helpString: `
12861325 <div>
@@ -1291,7 +1330,10 @@ export function initDefaultSlashCommands() {
12911330 <strong>Example:</strong>
12921331 <ul>
12931332 <li>
12941333 <pre><code>/popup large=on wide=on okButton="SubmitConfirm" EnterPlease someconfirm text:this action.</code></pre>
1334+ </li>
1335+ <li>
1336+ <pre><code>/popup okButton="Left" cancelButton="Right" result=true Do you want to go left or right? | /echo 0 means right, 1 means left. Choice: {{pipe}}</code></pre>
12951337 </li>
12961338 </ul>
12971339 </div>
@@ -1574,6 +1616,13 @@ export function initDefaultSlashCommands() {
15741616 defaultValue: 'true',
15751617 enumList: commonEnumProviders.boolean('trueFalse')(),
15761618 }),
1619+ SlashCommandNamedArgument.fromProps({
1620+ name: 'quiet',
1621+ description: 'suppress the toast message on API change',
1622+ typeList: [ARGUMENT_TYPE.BOOLEAN],
1623+ defaultValue: 'false',
1624+ enumList: commonEnumProviders.boolean('trueFalse')(),
1625+ }),
15771626 ],
15781627 unnamedArgumentList: [
15791628 SlashCommandArgument.fromProps({
@@ -1882,16 +1931,21 @@ async function buttonsCallback(args, text) {
18821931}
18831932
18841933async function popupCallback(args, value) {
18851934 const safeValuesafeBody = DOMPurify.sanitize(value || '');
1935+ const safeHeader = args?.header && typeof args?.header === 'string' ? DOMPurify.sanitize(args.header) : null;
1936+ const requestedResult = isTrueBoolean(args?.result);
1937+
1938+ /** @type {import('./popup.js').PopupOptions} */
18861939 const popupOptions = {
18871940 large: isTrueBoolean(args?.large),
18881941 wide: isTrueBoolean(args?.wide),
1942+ wider: isTrueBoolean(args?.wider),
1943+ transparent: isTrueBoolean(args?.transparent),
18891944 okButton: args?.okButton !== undefined && typeof args?.okButton === 'string' ? args.okButton : 'Ok',
1945+ cancelButton: args?.cancelButton !== undefined && typeof args?.cancelButton === 'string' ? args.cancelButton : null,
18901946 };
1891- await delay(1);
1947+ const result = await Popup.show.text(safeHeader, safeBody, popupOptions);
1892- await callGenericPopup(safeValue, POPUP_TYPE.TEXT, '', popupOptions);
1948+ return String(requestedResult ? result ?? '' : value);
1893- await delay(1);
1894- return String(value);
18951949}
18961950
18971951async function getMessagesCallback(args, value) {
@@ -3530,10 +3584,12 @@ function setPromptEntryCallback(args, targetState) {
35303584 * @param {object} args - named args
35313585 * @param {string?} [args.api=null] - the API name to set/get the URL for
35323586 * @param {string?} [args.connect=true] - whether to connect to the API after setting
3587+ * @param {string?} [args.quiet=false] - whether to suppress toasts
35333588 * @param {string} url - the API URL to set
35343589 * @returns {Promise<string>}
35353590 */
35363591async function setApiUrlCallback({ api = null, connect = 'true', quiet = 'false' }, url) {
3592+ const isQuiet = isTrueBoolean(quiet);
35373593 const autoConnect = isTrueBoolean(connect);
35383594
35393595 // Special handling for Chat Completion Custom OpenAI compatible, that one can also support API url handling
@@ -3582,22 +3638,26 @@ async function setApiUrlCallback({ api = null, connect = 'true' }, url) {
35823638
35833639 // Do some checks and get the api type we are targeting with this command
35843640 if (api && !Object.values(textgen_types).includes(api)) {
35853641 !isQuiet && toastr.warning(`API '${api}' is not a valid text_gen API.`);
35863642 return '';
35873643 }
35883644 if (!api && !Object.values(textgen_types).includes(textgenerationwebui_settings.type)) {
35893645 !isQuiet && toastr.warning(`API '${textgenerationwebui_settings.type}' is not a valid text_gen API.`);
3646+ return '';
3647+ }
3648+ if (!api && main_api !== 'textgenerationwebui') {
3649+ !isQuiet && toastr.warning(`API type '${main_api}' does not support setting the server URL.`);
35903650 return '';
35913651 }
35923652 if (api && url && autoConnect && api !== textgenerationwebui_settings.type) {
35933653 !isQuiet && toastr.warning(`API '${api}' is not the currently selected API, so we cannot do an auto-connect. Consider switching to it via /api beforehand.`);
35943654 return '';
35953655 }
35963656 const type = api || textgenerationwebui_settings.type;
35973657
35983658 const inputSelector = SERVER_INPUTS[type];
35993659 if (!inputSelector) {
36003660 !isQuiet && toastr.warning(`API '${type}' does not have a server url input.`);
36013661 return '';
36023662 }
36033663