Merge branch 'staging' into feat/xtc
| @@ -246,7 +246,6 @@ You will need two mandatory directory mappings and a port mapping to allow Silly | |||
| 246 | 246 | ||
| 247 | ##### Additional Settings | 247 | ##### Additional Settings |
| 248 | 248 | ||
| 249 | - [TimeZone] - The timezone your instance should use. This is useful for making logs match your local time for easier troubleshooting. Use your TZ Identifier. (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) | ||
| 250 | - [DockerNet] - The docker network that the container should be created with a connection to. If you don't know what it is, see the [official Docker documentation](https://docs.docker.com/reference/cli/docker/network/). | 249 | - [DockerNet] - The docker network that the container should be created with a connection to. If you don't know what it is, see the [official Docker documentation](https://docs.docker.com/reference/cli/docker/network/). |
| 251 | - [version] - On the right-hand side of this GitHub page, you'll see "Packages". Select the "sillytavern" package and you'll see the image versions. The image tag "latest" will keep you up-to-date with the current release. You can also utilize "staging" and "release" tags that point to the nightly images of the respective branches, but this may not be appropriate, if you are utilizing extensions that could be broken, and may need time to update. | 250 | - [version] - On the right-hand side of this GitHub page, you'll see "Packages". Select the "sillytavern" package and you'll see the image versions. The image tag "latest" will keep you up-to-date with the current release. You can also utilize "staging" and "release" tags that point to the nightly images of the respective branches, but this may not be appropriate, if you are utilizing extensions that could be broken, and may need time to update. |
| 252 | 251 | ||
| @@ -255,7 +254,7 @@ You will need two mandatory directory mappings and a port mapping to allow Silly | |||
| 255 | 1. Open your Command Line | 254 | 1. Open your Command Line |
| 256 | 2. Run the following command | 255 | 2. Run the following command |
| 257 | 256 | ||
| 258 | `docker create --name='sillytavern' --net='[DockerNet]' -e TZ="[TimeZone]" -p '8000:8000/tcp' -v '[plugins]':'/home/node/app/plugins':'rw' -v '[config]':'/home/node/app/config':'rw' -v '[data]':'/home/node/app/data':'rw' 'ghcr.io/sillytavern/sillytavern:[version]'` | 257 | `docker create --name='sillytavern' --net='[DockerNet]' -p '8000:8000/tcp' -v '[plugins]':'/home/node/app/plugins':'rw' -v '[config]':'/home/node/app/config':'rw' -v '[data]':'/home/node/app/data':'rw' 'ghcr.io/sillytavern/sillytavern:[version]'` |
| 259 | 258 | ||
| 260 | > Note that 8000 is a default listening port. Don't forget to use an appropriate port if you change it in the config. | 259 | > Note that 8000 is a default listening port. Don't forget to use an appropriate port if you change it in the config. |
| 261 | 260 | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | FROM node:lts-alpine3.18 | 1 | FROM node:lts-alpine3.19 |
| 2 | 2 | ||
| 3 | # Arguments | 3 | # Arguments |
| 4 | ARG APP_HOME=/home/node/app | 4 | ARG APP_HOME=/home/node/app |
| @@ -90,9 +90,11 @@ whitelistImportDomains: | |||
| 90 | ## headers: | 90 | ## headers: |
| 91 | ## User-Agent: "Googlebot/2.1 (+http://www.google.com/bot.html)" | 91 | ## User-Agent: "Googlebot/2.1 (+http://www.google.com/bot.html)" |
| 92 | requestOverrides: [] | 92 | requestOverrides: [] |
| 93 | # -- PLUGIN CONFIGURATION -- | 93 | # -- EXTENSIONS CONFIGURATION -- |
| 94 | # Enable UI extensions | 94 | # Enable UI extensions |
| 95 | enableExtensions: true | 95 | enableExtensions: true |
| 96 | # Automatically update extensions when a release version changes | ||
| 97 | enableExtensionsAutoUpdate: true | ||
| 96 | # Extension settings | 98 | # Extension settings |
| 97 | extras: | 99 | extras: |
| 98 | # Disables automatic model download from HuggingFace | 100 | # Disables automatic model download from HuggingFace |
| @@ -126,7 +128,7 @@ ollama: | |||
| 126 | # Controls how long the model will stay loaded into memory following the request | 128 | # Controls how long the model will stay loaded into memory following the request |
| 127 | # * -1: Keep the model loaded indefinitely | 129 | # * -1: Keep the model loaded indefinitely |
| 128 | # * 0: Unload the model immediately after the request | 130 | # * 0: Unload the model immediately after the request |
| 129 | # * 5m: Keep the model loaded for 5 minutes after the request. Accepts duration strings (e.g. 5h30m40s) | 131 | # * N (any positive number): Keep the model loaded for N seconds after the request. |
| 130 | keepAlive: -1 | 132 | keepAlive: -1 |
| 131 | # -- ANTHROPIC CLAUDE API CONFIGURATION -- | 133 | # -- ANTHROPIC CLAUDE API CONFIGURATION -- |
| 132 | claude: | 134 | claude: |
| @@ -8,7 +8,7 @@ | |||
| 8 | "openrouter_force_instruct": false, | 8 | "openrouter_force_instruct": false, |
| 9 | "openrouter_group_models": false, | 9 | "openrouter_group_models": false, |
| 10 | "openrouter_sort_models": "alphabetically", | 10 | "openrouter_sort_models": "alphabetically", |
| 11 | "ai21_model": "j2-ultra", | 11 | "ai21_model": "jamba-1.5-large", |
| 12 | "mistralai_model": "mistral-large-latest", | 12 | "mistralai_model": "mistral-large-latest", |
| 13 | "custom_model": "", | 13 | "custom_model": "", |
| 14 | "custom_url": "", | 14 | "custom_url": "", |
| @@ -19,7 +19,6 @@ | |||
| 19 | "temperature": 1, | 19 | "temperature": 1, |
| 20 | "frequency_penalty": 0, | 20 | "frequency_penalty": 0, |
| 21 | "presence_penalty": 0, | 21 | "presence_penalty": 0, |
| 22 | "count_penalty": 0, | ||
| 23 | "top_p": 1, | 22 | "top_p": 1, |
| 24 | "top_k": 0, | 23 | "top_k": 0, |
| 25 | "top_a": 0, | 24 | "top_a": 0, |
| @@ -233,8 +232,6 @@ | |||
| 233 | "assistant_prefill": "", | 232 | "assistant_prefill": "", |
| 234 | "assistant_impersonation": "", | 233 | "assistant_impersonation": "", |
| 235 | "human_sysprompt_message": "Let's get started. Please generate your response based on the information and instructions provided above.", | 234 | "human_sysprompt_message": "Let's get started. Please generate your response based on the information and instructions provided above.", |
| 236 | "use_ai21_tokenizer": false, | ||
| 237 | "use_google_tokenizer": false, | ||
| 238 | "claude_use_sysprompt": false, | 235 | "claude_use_sysprompt": false, |
| 239 | "use_alt_scale": false, | 236 | "use_alt_scale": false, |
| 240 | "squash_system_messages": false, | 237 | "squash_system_messages": false, |
| @@ -142,6 +142,7 @@ | |||
| 142 | "timestamps_enabled": true, | 142 | "timestamps_enabled": true, |
| 143 | "timestamp_model_icon": true, | 143 | "timestamp_model_icon": true, |
| 144 | "mesIDDisplay_enabled": false, | 144 | "mesIDDisplay_enabled": false, |
| 145 | "hideChatAvatars_enabled": false, | ||
| 145 | "max_context_unlocked": false, | 146 | "max_context_unlocked": false, |
| 146 | "prefer_character_prompt": true, | 147 | "prefer_character_prompt": true, |
| 147 | "prefer_character_jailbreak": true, | 148 | "prefer_character_jailbreak": true, |
| @@ -195,7 +196,15 @@ | |||
| 195 | "enableLabMode": false, | 196 | "enableLabMode": false, |
| 196 | "enableZenSliders": false, | 197 | "enableZenSliders": false, |
| 197 | "ui_mode": 1, | 198 | "ui_mode": 1, |
| 198 | "forbid_external_media": true | 199 | "forbid_external_media": true, |
| 200 | "stscript": { | ||
| 201 | "parser": { | ||
| 202 | "flags": { | ||
| 203 | "1": true, | ||
| 204 | "2": true | ||
| 205 | } | ||
| 206 | } | ||
| 207 | } | ||
| 199 | }, | 208 | }, |
| 200 | "extension_settings": { | 209 | "extension_settings": { |
| 201 | "apiUrl": "http://localhost:5100", | 210 | "apiUrl": "http://localhost:5100", |
| @@ -451,7 +460,6 @@ | |||
| 451 | "temp_openai": 1.0, | 460 | "temp_openai": 1.0, |
| 452 | "freq_pen_openai": 0, | 461 | "freq_pen_openai": 0, |
| 453 | "pres_pen_openai": 0, | 462 | "pres_pen_openai": 0, |
| 454 | "count_pen": 0, | ||
| 455 | "top_p_openai": 1, | 463 | "top_p_openai": 1, |
| 456 | "top_k_openai": 0, | 464 | "top_k_openai": 0, |
| 457 | "stream_openai": true, | 465 | "stream_openai": true, |
| @@ -613,7 +621,7 @@ | |||
| 613 | "wi_format": "{0}", | 621 | "wi_format": "{0}", |
| 614 | "openai_model": "gpt-4-turbo", | 622 | "openai_model": "gpt-4-turbo", |
| 615 | "claude_model": "claude-3-5-sonnet-20240620", | 623 | "claude_model": "claude-3-5-sonnet-20240620", |
| 616 | "ai21_model": "j2-ultra", | 624 | "ai21_model": "jamba-1.5-large", |
| 617 | "windowai_model": "", | 625 | "windowai_model": "", |
| 618 | "openrouter_model": "OR_Website", | 626 | "openrouter_model": "OR_Website", |
| 619 | "jailbreak_system": true, | 627 | "jailbreak_system": true, |
| @@ -624,7 +632,6 @@ | |||
| 624 | "show_external_models": false, | 632 | "show_external_models": false, |
| 625 | "proxy_password": "", | 633 | "proxy_password": "", |
| 626 | "assistant_prefill": "", | 634 | "assistant_prefill": "", |
| 627 | "assistant_impersonation": "", | 635 | "assistant_impersonation": "" |
| 628 | "use_ai21_tokenizer": false | ||
| 629 | } | 636 | } |
| 630 | } | 637 | } |
| @@ -23,6 +23,7 @@ | |||
| 23 | "timestamps_enabled": true, | 23 | "timestamps_enabled": true, |
| 24 | "timestamp_model_icon": false, | 24 | "timestamp_model_icon": false, |
| 25 | "mesIDDisplay_enabled": true, | 25 | "mesIDDisplay_enabled": true, |
| 26 | "hideChatAvatars_enabled": false, | ||
| 26 | "message_token_count_enabled": false, | 27 | "message_token_count_enabled": false, |
| 27 | "expand_message_actions": false, | 28 | "expand_message_actions": false, |
| 28 | "enableZenSliders": false, | 29 | "enableZenSliders": false, |
| @@ -23,6 +23,7 @@ | |||
| 23 | "timestamps_enabled": true, | 23 | "timestamps_enabled": true, |
| 24 | "timestamp_model_icon": true, | 24 | "timestamp_model_icon": true, |
| 25 | "mesIDDisplay_enabled": true, | 25 | "mesIDDisplay_enabled": true, |
| 26 | "hideChatAvatars_enabled": false, | ||
| 26 | "message_token_count_enabled": false, | 27 | "message_token_count_enabled": false, |
| 27 | "expand_message_actions": false, | 28 | "expand_message_actions": false, |
| 28 | "enableZenSliders": false, | 29 | "enableZenSliders": false, |
| @@ -23,6 +23,7 @@ | |||
| 23 | "timestamps_enabled": true, | 23 | "timestamps_enabled": true, |
| 24 | "timestamp_model_icon": true, | 24 | "timestamp_model_icon": true, |
| 25 | "mesIDDisplay_enabled": false, | 25 | "mesIDDisplay_enabled": false, |
| 26 | "hideChatAvatars_enabled": false, | ||
| 26 | "message_token_count_enabled": false, | 27 | "message_token_count_enabled": false, |
| 27 | "expand_message_actions": false, | 28 | "expand_message_actions": false, |
| 28 | "enableZenSliders": "", | 29 | "enableZenSliders": "", |
Binary file
| @@ -1,12 +1,12 @@ | |||
| 1 | { | 1 | { |
| 2 | "name": "sillytavern", | 2 | "name": "sillytavern", |
| 3 | "version": "1.12.4", | 3 | "version": "1.12.5", |
| 4 | "lockfileVersion": 3, | 4 | "lockfileVersion": 3, |
| 5 | "requires": true, | 5 | "requires": true, |
| 6 | "packages": { | 6 | "packages": { |
| 7 | "": { | 7 | "": { |
| 8 | "name": "sillytavern", | 8 | "name": "sillytavern", |
| 9 | "version": "1.12.4", | 9 | "version": "1.12.5", |
| 10 | "hasInstallScript": true, | 10 | "hasInstallScript": true, |
| 11 | "license": "AGPL-3.0", | 11 | "license": "AGPL-3.0", |
| 12 | "dependencies": { | 12 | "dependencies": { |
| @@ -71,7 +71,7 @@ | |||
| 71 | "type": "git", | 71 | "type": "git", |
| 72 | "url": "https://github.com/SillyTavern/SillyTavern.git" | 72 | "url": "https://github.com/SillyTavern/SillyTavern.git" |
| 73 | }, | 73 | }, |
| 74 | "version": "1.12.4", | 74 | "version": "1.12.5", |
| 75 | "scripts": { | 75 | "scripts": { |
| 76 | "start": "node server.js", | 76 | "start": "node server.js", |
| 77 | "start:no-csrf": "node server.js --disableCsrf", | 77 | "start:no-csrf": "node server.js --disableCsrf", |
Binary file
| @@ -5,7 +5,7 @@ | |||
| 5 | <title>SillyTavern</title> | 5 | <title>SillyTavern</title> |
| 6 | <base href="/"> | 6 | <base href="/"> |
| 7 | <meta charset="utf-8"> | 7 | <meta charset="utf-8"> |
| 8 | <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1, maximum-scale=1.0, user-scalable=no"> | 8 | <meta name="viewport" content="width=device-width, viewport-fit=cover, initial-scale=1, maximum-scale=1.0, user-scalable=no, interactive-widget=resizes-content"> |
| 9 | <meta name="apple-mobile-web-app-capable" content="yes"> | 9 | <meta name="apple-mobile-web-app-capable" content="yes"> |
| 10 | <meta name="darkreader-lock"> | 10 | <meta name="darkreader-lock"> |
| 11 | <meta name="robots" content="noindex, nofollow" /> | 11 | <meta name="robots" content="noindex, nofollow" /> |
| @@ -436,7 +436,7 @@ | |||
| 436 | </div> | 436 | </div> |
| 437 | </div> | 437 | </div> |
| 438 | </div> | 438 | </div> |
| 439 | <div data-newbie-hidden class="range-block" data-source="openai,openrouter,ai21,custom,cohere,perplexity,groq"> | 439 | <div data-newbie-hidden class="range-block" data-source="openai,openrouter,custom,cohere,perplexity,groq"> |
| 440 | <div class="range-block-title" data-i18n="Frequency Penalty"> | 440 | <div class="range-block-title" data-i18n="Frequency Penalty"> |
| 441 | Frequency Penalty | 441 | Frequency Penalty |
| 442 | </div> | 442 | </div> |
| @@ -449,7 +449,7 @@ | |||
| 449 | </div> | 449 | </div> |
| 450 | </div> | 450 | </div> |
| 451 | </div> | 451 | </div> |
| 452 | <div data-newbie-hidden class="range-block" data-source="openai,openrouter,ai21,custom,cohere,perplexity,groq"> | 452 | <div data-newbie-hidden class="range-block" data-source="openai,openrouter,custom,cohere,perplexity,groq"> |
| 453 | <div class="range-block-title" data-i18n="Presence Penalty"> | 453 | <div class="range-block-title" data-i18n="Presence Penalty"> |
| 454 | Presence Penalty | 454 | Presence Penalty |
| 455 | </div> | 455 | </div> |
| @@ -462,20 +462,7 @@ | |||
| 462 | </div> | 462 | </div> |
| 463 | </div> | 463 | </div> |
| 464 | </div> | 464 | </div> |
| 465 | <div data-newbie-hidden class="range-block" data-source="ai21"> | 465 | <div data-newbie-hidden class="range-block" data-source="claude,openrouter,makersuite,cohere,perplexity"> |
| 466 | <div class="range-block-title" data-i18n="Count Penalty"> | ||
| 467 | Count Penalty | ||
| 468 | </div> | ||
| 469 | <div class="range-block-range-and-counter"> | ||
| 470 | <div class="range-block-range"> | ||
| 471 | <input type="range" id="count_pen" name="volume" min="0" max="1" step="0.01"> | ||
| 472 | </div> | ||
| 473 | <div class="range-block-counter"> | ||
| 474 | <input type="number" min="0" max="1" step="0.01" data-for="count_pen" id="count_pen_counter"> | ||
| 475 | </div> | ||
| 476 | </div> | ||
| 477 | </div> | ||
| 478 | <div data-newbie-hidden class="range-block" data-source="claude,openrouter,ai21,makersuite,cohere,perplexity"> | ||
| 479 | <div class="range-block-title" data-i18n="Top K"> | 466 | <div class="range-block-title" data-i18n="Top K"> |
| 480 | Top K | 467 | Top K |
| 481 | </div> | 468 | </div> |
| @@ -1814,22 +1801,6 @@ | |||
| 1814 | </select> | 1801 | </select> |
| 1815 | </div> | 1802 | </div> |
| 1816 | </div> | 1803 | </div> |
| 1817 | <div class="range-block" data-source="ai21"> | ||
| 1818 | <label for="use_ai21_tokenizer" title="Use AI21 Tokenizer" data-i18n="[title]Use AI21 Tokenizer" class="checkbox_label widthFreeExpand"> | ||
| 1819 | <input id="use_ai21_tokenizer" type="checkbox" /><span data-i18n="Use AI21 Tokenizer">Use AI21 Tokenizer</span> | ||
| 1820 | </label> | ||
| 1821 | <div class="toggle-description justifyLeft"> | ||
| 1822 | <span data-i18n="Use the appropriate tokenizer for Jurassic models, which is more efficient than GPT's.">Use the appropriate tokenizer for Jurassic models, which is more efficient than GPT's.</span> | ||
| 1823 | </div> | ||
| 1824 | </div> | ||
| 1825 | <div class="range-block" data-source="makersuite"> | ||
| 1826 | <label for="use_google_tokenizer" title="Use Google Tokenizer" data-i18n="[title]Use Google Tokenizer" class="checkbox_label widthFreeExpand"> | ||
| 1827 | <input id="use_google_tokenizer" type="checkbox" /><span data-i18n="Use Google Tokenizer">Use Google Tokenizer</span> | ||
| 1828 | </label> | ||
| 1829 | <div class="toggle-description justifyLeft"> | ||
| 1830 | <span data-i18n="Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.">Use the appropriate tokenizer for Google models via their API. Slower prompt processing, but offers much more accurate token counting.</span> | ||
| 1831 | </div> | ||
| 1832 | </div> | ||
| 1833 | <div class="range-block" data-source="makersuite"> | 1804 | <div class="range-block" data-source="makersuite"> |
| 1834 | <label for="use_makersuite_sysprompt" class="checkbox_label widthFreeExpand"> | 1805 | <label for="use_makersuite_sysprompt" class="checkbox_label widthFreeExpand"> |
| 1835 | <input id="use_makersuite_sysprompt" type="checkbox" /> | 1806 | <input id="use_makersuite_sysprompt" type="checkbox" /> |
| @@ -1875,7 +1846,7 @@ | |||
| 1875 | <div class="fa-solid fa-clock-rotate-left"></div> | 1846 | <div class="fa-solid fa-clock-rotate-left"></div> |
| 1876 | </div> | 1847 | </div> |
| 1877 | </div> | 1848 | </div> |
| 1878 | <textarea id="claude_human_sysprompt_textarea" class="text_pole textarea_compact" rows="4" maxlength="10000" data-i18n="[placeholder]Human message" placeholder="Human message, instruction, etc. Adds nothing when empty, i.e. requires a new prompt with the role 'user'."></textarea> | 1849 | <textarea id="claude_human_sysprompt_textarea" class="text_pole textarea_compact" rows="4" data-i18n="[placeholder]Human message" placeholder="Human message, instruction, etc. Adds nothing when empty, i.e. requires a new prompt with the role 'user'."></textarea> |
| 1879 | </div> | 1850 | </div> |
| 1880 | </div> | 1851 | </div> |
| 1881 | </div> | 1852 | </div> |
| @@ -2460,7 +2431,7 @@ | |||
| 2460 | <option value="claude">Claude</option> | 2431 | <option value="claude">Claude</option> |
| 2461 | <option value="cohere">Cohere</option> | 2432 | <option value="cohere">Cohere</option> |
| 2462 | <option value="groq">Groq</option> | 2433 | <option value="groq">Groq</option> |
| 2463 | <option value="makersuite">Google MakerSuite</option> | 2434 | <option value="makersuite">Google AI Studio</option> |
| 2464 | <option value="mistralai">MistralAI</option> | 2435 | <option value="mistralai">MistralAI</option> |
| 2465 | <option value="openrouter">OpenRouter</option> | 2436 | <option value="openrouter">OpenRouter</option> |
| 2466 | <option value="perplexity">Perplexity</option> | 2437 | <option value="perplexity">Perplexity</option> |
| @@ -2814,16 +2785,18 @@ | |||
| 2814 | <div> | 2785 | <div> |
| 2815 | <h4 data-i18n="AI21 Model">AI21 Model</h4> | 2786 | <h4 data-i18n="AI21 Model">AI21 Model</h4> |
| 2816 | <select id="model_ai21_select"> | 2787 | <select id="model_ai21_select"> |
| 2817 | <optgroup label="Latest"> | 2788 | <optgroup label="Jamba 1.5"> |
| 2818 | <option value="j2-ultra">j2-ultra</option> | 2789 | <option value="jamba-1.5-mini">jamba-1.5-mini</option> |
| 2819 | <option value="j2-mid">j2-mid</option> | 2790 | <option value="jamba-1.5-large">jamba-1.5-large</option> |
| 2820 | <option value="j2-light">j2-light</option> | 2791 | </optgroup> |
| 2792 | <optgroup label="Jamba-Instruct (Deprecated)"> | ||
| 2793 | <option value="jamba-instruct-preview">jamba-instruct-preview</option> | ||
| 2821 | </optgroup> | 2794 | </optgroup> |
| 2822 | </select> | 2795 | </select> |
| 2823 | </div> | 2796 | </div> |
| 2824 | </form> | 2797 | </form> |
| 2825 | <form id="makersuite_form" data-source="makersuite" action="javascript:void(null);" method="post" enctype="multipart/form-data"> | 2798 | <form id="makersuite_form" data-source="makersuite" action="javascript:void(null);" method="post" enctype="multipart/form-data"> |
| 2826 | <h4 data-i18n="MakerSuite API Key">MakerSuite API Key</h4> | 2799 | <h4 data-i18n="Google AI Studio API Key">Google AI Studio API Key</h4> |
| 2827 | <div class="flex-container"> | 2800 | <div class="flex-container"> |
| 2828 | <input id="api_key_makersuite" name="api_key_makersuite" class="text_pole flex1" maxlength="500" value="" type="text" autocomplete="off"> | 2801 | <input id="api_key_makersuite" name="api_key_makersuite" class="text_pole flex1" maxlength="500" value="" type="text" autocomplete="off"> |
| 2829 | <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_makersuite"></div> | 2802 | <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_makersuite"></div> |
| @@ -2847,8 +2820,11 @@ | |||
| 2847 | </optgroup> | 2820 | </optgroup> |
| 2848 | <optgroup label="Subversions"> | 2821 | <optgroup label="Subversions"> |
| 2849 | <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experiment 2024-08-01</option> | 2822 | <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experiment 2024-08-01</option> |
| 2823 | <option value="gemini-1.5-pro-exp-0827">Gemini 1.5 Pro Experiment 2024-08-27</option> | ||
| 2850 | <option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option> | 2824 | <option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option> |
| 2851 | <option value="gemini-1.5-pro-001">Gemini 1.5 Pro [001]</option> | 2825 | <option value="gemini-1.5-pro-001">Gemini 1.5 Pro [001]</option> |
| 2826 | <option value="gemini-1.5-flash-exp-0827">Gemini 1.5 Flash Experiment 2024-08-27</option> | ||
| 2827 | <option value="gemini-1.5-flash-8b-exp-0827">Gemini 1.5 Flash 8B Experiment 2024-08-27</option> | ||
| 2852 | <option value="gemini-1.5-flash-latest">Gemini 1.5 Flash [latest]</option> | 2828 | <option value="gemini-1.5-flash-latest">Gemini 1.5 Flash [latest]</option> |
| 2853 | <option value="gemini-1.5-flash-001">Gemini 1.5 Flash [001]</option> | 2829 | <option value="gemini-1.5-flash-001">Gemini 1.5 Flash [001]</option> |
| 2854 | <option value="gemini-1.0-pro-latest">Gemini 1.0 Pro [latest]</option> | 2830 | <option value="gemini-1.0-pro-latest">Gemini 1.0 Pro [latest]</option> |
| @@ -2978,6 +2954,8 @@ | |||
| 2978 | <option value="command">command</option> | 2954 | <option value="command">command</option> |
| 2979 | <option value="command-r">command-r</option> | 2955 | <option value="command-r">command-r</option> |
| 2980 | <option value="command-r-plus">command-r-plus</option> | 2956 | <option value="command-r-plus">command-r-plus</option> |
| 2957 | <option value="command-r-08-2024">command-r-08-2024</option> | ||
| 2958 | <option value="command-r-plus-08-2024">command-r-plus-08-2024</option> | ||
| 2981 | </optgroup> | 2959 | </optgroup> |
| 2982 | <optgroup label="Nightly"> | 2960 | <optgroup label="Nightly"> |
| 2983 | <option value="command-light-nightly">command-light-nightly</option> | 2961 | <option value="command-light-nightly">command-light-nightly</option> |
| @@ -3473,6 +3451,7 @@ | |||
| 3473 | <option value="3">Llama 1/2</option> | 3451 | <option value="3">Llama 1/2</option> |
| 3474 | <option value="12">Llama 3</option> | 3452 | <option value="12">Llama 3</option> |
| 3475 | <option value="13">Gemma / Gemini</option> | 3453 | <option value="13">Gemma / Gemini</option> |
| 3454 | <option value="14">Jamba</option> | ||
| 3476 | <option value="4">NerdStash (NovelAI Clio)</option> | 3455 | <option value="4">NerdStash (NovelAI Clio)</option> |
| 3477 | <option value="5">NerdStash v2 (NovelAI Kayra)</option> | 3456 | <option value="5">NerdStash v2 (NovelAI Kayra)</option> |
| 3478 | <option value="7">Mistral</option> | 3457 | <option value="7">Mistral</option> |
| @@ -3645,6 +3624,7 @@ | |||
| 3645 | <div class="alignitemscenter flex-container flexFlowColumn flexGrow flexShrink gap0 flexBasis48p" title="Scan chronologically until reached min entries or token budget." data-i18n="[title]Scan chronologically until reached min entries or token budget."> | 3624 | <div class="alignitemscenter flex-container flexFlowColumn flexGrow flexShrink gap0 flexBasis48p" title="Scan chronologically until reached min entries or token budget." data-i18n="[title]Scan chronologically until reached min entries or token budget."> |
| 3646 | <small> | 3625 | <small> |
| 3647 | <span data-i18n="Min Activations">Min Activations</span> | 3626 | <span data-i18n="Min Activations">Min Activations</span> |
| 3627 | <div class="fa-solid fa-triangle-exclamation opacity50p" data-i18n="[title](disabled when max recursion steps are used)" title="(disabled when max recursion steps are used)"></div> | ||
| 3648 | </small> | 3628 | </small> |
| 3649 | <input class="neo-range-slider" type="range" id="world_info_min_activations" name="world_info_min_activations" min="0" max="100" step="1"> | 3629 | <input class="neo-range-slider" type="range" id="world_info_min_activations" name="world_info_min_activations" min="0" max="100" step="1"> |
| 3650 | <input class="neo-range-input" type="number" min="0" max="100" step="1" data-for="world_info_min_activations" id="world_info_min_activations_counter"> | 3630 | <input class="neo-range-input" type="number" min="0" max="100" step="1" data-for="world_info_min_activations" id="world_info_min_activations_counter"> |
| @@ -3658,6 +3638,14 @@ | |||
| 3658 | <input class="neo-range-slider" type="range" id="world_info_min_activations_depth_max" name="volume" min="0" max="100" step="1"> | 3638 | <input class="neo-range-slider" type="range" id="world_info_min_activations_depth_max" name="volume" min="0" max="100" step="1"> |
| 3659 | <input class="neo-range-input" type="number" min="0" max="100" step="1" data-for="world_info_min_activations_depth_max" id="world_info_min_activations_depth_max_counter"> | 3639 | <input class="neo-range-input" type="number" min="0" max="100" step="1" data-for="world_info_min_activations_depth_max" id="world_info_min_activations_depth_max_counter"> |
| 3660 | </div> | 3640 | </div> |
| 3641 | <div class="alignitemscenter flex-container flexFlowColumn flexGrow flexShrink gap0 flexBasis48p" title="Cap the number of entry activation recursions" data-i18n="[title]Cap the number of entry activation recursions"> | ||
| 3642 | <small> | ||
| 3643 | <span data-i18n="Max Recursion Steps">Max Recursion Steps</span> | ||
| 3644 | <div class="fa-solid fa-triangle-exclamation opacity50p" data-i18n="[title]0 = unlimited, 1 = scans once and doesn't recurse, 2 = scans once and recurses once, etc\n(disabled when min activations are used)" title="0 = unlimited, 1 = scans once and doesn't recurse, 2 = scans once and recurses once, etc (disabled when min activations are used)"></div> | ||
| 3645 | </small> | ||
| 3646 | <input class="neo-range-slider" type="range" id="world_info_max_recursion_steps" name="world_info_max_recursion_steps" min="0" max="10" step="1"> | ||
| 3647 | <input class="neo-range-input" type="number" min="0" max="10" step="1" data-for="world_info_max_recursion_steps" id="world_info_max_recursion_steps_counter"> | ||
| 3648 | </div> | ||
| 3661 | 3649 | ||
| 3662 | <div class="alignitemscenter flex-container flexFlowColumn flexGrow flexShrink flexBasis48p"> | 3650 | <div class="alignitemscenter flex-container flexFlowColumn flexGrow flexShrink flexBasis48p"> |
| 3663 | <small data-i18n="Insertion Strategy"> | 3651 | <small data-i18n="Insertion Strategy"> |
| @@ -3921,8 +3909,8 @@ | |||
| 3921 | <span data-i18n="Font Scale">Font Scale</span> | 3909 | <span data-i18n="Font Scale">Font Scale</span> |
| 3922 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Font size" title="Font size"></div> | 3910 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Font size" title="Font size"></div> |
| 3923 | </small> | 3911 | </small> |
| 3924 | <input class="neo-range-slider" type="range" id="font_scale" name="font_scale" min="0.8" max="1.2" step="0.01"> | 3912 | <input class="neo-range-slider" type="range" id="font_scale" name="font_scale" min="0.5" max="1.5" step="0.01"> |
| 3925 | <input class="neo-range-input" type="number" min="0.8" max="1.2" step="0.01" data-for="font_scale" id="font_scale_counter"> | 3913 | <input class="neo-range-input" type="number" min="0.5" max="1.5" step="0.01" data-for="font_scale" id="font_scale_counter"> |
| 3926 | </div> | 3914 | </div> |
| 3927 | 3915 | ||
| 3928 | <div class="alignitemscenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0"> | 3916 | <div class="alignitemscenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0"> |
| @@ -4134,7 +4122,7 @@ | |||
| 4134 | <input id="movingUImode" type="checkbox" /> | 4122 | <input id="movingUImode" type="checkbox" /> |
| 4135 | <small data-i18n="Movable UI Panels">MovingUI <i class="fa-solid fa-desktop"></i></small> | 4123 | <small data-i18n="Movable UI Panels">MovingUI <i class="fa-solid fa-desktop"></i></small> |
| 4136 | </label> | 4124 | </label> |
| 4137 | <div data-newbie-hidden id="movingUIreset" title="Reset MovingUI panel sizes/locations." class="menu_button margin0" data-i18n="[title]Reset MovingUI panel sizes/locations."><i class=" fa-solid fa-recycle margin-r5"></i> Reset</div> | 4125 | <div data-newbie-hidden id="movingUIreset" title="Reset MovingUI panel sizes/locations." class="menu_button margin0" data-i18n="[title]Reset MovingUI panel sizes/locations."><i class=" fa-solid fa-recycle margin-r5"></i> <span data-i18n="mui_reset">Reset</span></div> |
| 4138 | </div> | 4126 | </div> |
| 4139 | <div data-newbie-hidden id="MovingUI-presets-block" class="flex-container alignitemscenter"> | 4127 | <div data-newbie-hidden id="MovingUI-presets-block" class="flex-container alignitemscenter"> |
| 4140 | <div class="flex-container alignItemsFlexEnd"> | 4128 | <div class="flex-container alignItemsFlexEnd"> |
| @@ -4590,6 +4578,7 @@ | |||
| 4590 | <div data-newbie-hidden> | 4578 | <div data-newbie-hidden> |
| 4591 | <label for="persona_description_position" data-i18n="Position:">Position:</label> | 4579 | <label for="persona_description_position" data-i18n="Position:">Position:</label> |
| 4592 | <select id="persona_description_position"> | 4580 | <select id="persona_description_position"> |
| 4581 | <option value="9" data-i18n="None (disabled)">None (disabled)</option> | ||
| 4593 | <option value="0" data-i18n="In Story String / Prompt Manager">In Story String / Prompt Manager</option> | 4582 | <option value="0" data-i18n="In Story String / Prompt Manager">In Story String / Prompt Manager</option> |
| 4594 | <option value="2" data-i18n="Top of Author's Note">Top of Author's Note</option> | 4583 | <option value="2" data-i18n="Top of Author's Note">Top of Author's Note</option> |
| 4595 | <option value="3" data-i18n="Bottom of Author's Note">Bottom of Author's Note</option> | 4584 | <option value="3" data-i18n="Bottom of Author's Note">Bottom of Author's Note</option> |
| @@ -5615,13 +5604,16 @@ | |||
| 5615 | <div class="flex-container wide100p flexGap10"> | 5604 | <div class="flex-container wide100p flexGap10"> |
| 5616 | <div class="flex4 flex-container flexFlowColumn flexNoGap"> | 5605 | <div class="flex4 flex-container flexFlowColumn flexNoGap"> |
| 5617 | <div class="flex-container justifySpaceBetween"> | 5606 | <div class="flex-container justifySpaceBetween"> |
| 5618 | <small for="characterFilter" data-i18n="Filter to Character(s)"> | 5607 | <small for="characterFilter" data-i18n="Filter to Characters or Tags"> |
| 5619 | Filter to Character(s) | 5608 | Filter to Characters or Tags |
| 5620 | </small> | 5609 | </small> |
| 5621 | <label class="checkbox_label flexNoGap margin-r5" for="character_exclusion"> | 5610 | <label class="checkbox_label flexNoGap margin-r5" for="character_exclusion"> |
| 5622 | <input type="checkbox" name="character_exclusion" /> | 5611 | <input type="checkbox" name="character_exclusion" /> |
| 5623 | <span> | 5612 | <span> |
| 5624 | <small data-i18n="Character Exclusion">Character Exclusion</small> | 5613 | <small title="Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry" data-i18n="[title]Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry"> |
| 5614 | <span data-i18n="Exclude">Exclude</span> | ||
| 5615 | <div class="fa-solid fa-circle-info opacity50p"></div> | ||
| 5616 | </small> | ||
| 5625 | </span> | 5617 | </span> |
| 5626 | </label> | 5618 | </label> |
| 5627 | </div> | 5619 | </div> |
| @@ -6577,6 +6569,7 @@ | |||
| 6577 | <script src="lib/jquery-cookie-1.4.1.min.js"></script> | 6569 | <script src="lib/jquery-cookie-1.4.1.min.js"></script> |
| 6578 | <script src="lib/jquery.ui.touch-punch.min.js"></script> | 6570 | <script src="lib/jquery.ui.touch-punch.min.js"></script> |
| 6579 | <script src="lib/showdown.min.js"></script> | 6571 | <script src="lib/showdown.min.js"></script> |
| 6572 | <script src="lib/showdown-patch.js"></script> | ||
| 6580 | <script src="lib/showdown-katex.min.js"></script> | 6573 | <script src="lib/showdown-katex.min.js"></script> |
| 6581 | <script src="lib/popper.js"></script> | 6574 | <script src="lib/popper.js"></script> |
| 6582 | <script src="lib/purify.min.js"></script> | 6575 | <script src="lib/purify.min.js"></script> |
| @@ -0,0 +1,24 @@ | |||
| 1 | showdown.subParser('unhashHTMLSpans', function (text, options, globals) { | ||
| 2 | 'use strict'; | ||
| 3 | text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals); | ||
| 4 | |||
| 5 | for (var i = 0; i < globals.gHtmlSpans.length; ++i) { | ||
| 6 | var repText = globals.gHtmlSpans[i], | ||
| 7 | // limiter to prevent infinite loop (assume 10 as limit for recurse) | ||
| 8 | limit = 0; | ||
| 9 | |||
| 10 | while (/¨C(\d+)C/.test(repText)) { | ||
| 11 | var num = RegExp.$1; | ||
| 12 | repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]); | ||
| 13 | if (limit === 10000) { | ||
| 14 | console.error('maximum nesting of 10000 spans reached!!!'); | ||
| 15 | break; | ||
| 16 | } | ||
| 17 | ++limit; | ||
| 18 | } | ||
| 19 | text = text.replace('¨C' + i + 'C', repText); | ||
| 20 | } | ||
| 21 | |||
| 22 | text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals); | ||
| 23 | return text; | ||
| 24 | }); | ||
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "طريقة بديلة", | 390 | "Alt Method": "طريقة بديلة", |
| 391 | "AI21 API Key": "مفتاح API لـ AI21", | 391 | "AI21 API Key": "مفتاح API لـ AI21", |
| 392 | "AI21 Model": "نموذج AI21", | 392 | "AI21 Model": "نموذج AI21", |
| 393 | "MakerSuite API Key": "مفتاح واجهة برمجة تطبيقات MakerSuite", | 393 | "Google AI Studio API Key": "مفتاح واجهة برمجة تطبيقات Google AI Studio", |
| 394 | "Google Model": "نموذج جوجل", | 394 | "Google Model": "نموذج جوجل", |
| 395 | "MistralAI API Key": "مفتاح واجهة برمجة التطبيقات MistralAI", | 395 | "MistralAI API Key": "مفتاح واجهة برمجة التطبيقات MistralAI", |
| 396 | "MistralAI Model": "نموذج ميسترال آي آي", | 396 | "MistralAI Model": "نموذج ميسترال آي آي", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "Alternative Methode", | 390 | "Alt Method": "Alternative Methode", |
| 391 | "AI21 API Key": "AI21 API-Schlüssel", | 391 | "AI21 API Key": "AI21 API-Schlüssel", |
| 392 | "AI21 Model": "AI21-Modell", | 392 | "AI21 Model": "AI21-Modell", |
| 393 | "MakerSuite API Key": "MakerSuite API-Schlüssel", | 393 | "Google AI Studio API Key": "Google AI Studio API-Schlüssel", |
| 394 | "Google Model": "Google-Modell", | 394 | "Google Model": "Google-Modell", |
| 395 | "MistralAI API Key": "MistralAI API-Schlüssel", | 395 | "MistralAI API Key": "MistralAI API-Schlüssel", |
| 396 | "MistralAI Model": "MistralAI-Modell", | 396 | "MistralAI Model": "MistralAI-Modell", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "Método alternativo", | 390 | "Alt Method": "Método alternativo", |
| 391 | "AI21 API Key": "Clave API de AI21", | 391 | "AI21 API Key": "Clave API de AI21", |
| 392 | "AI21 Model": "Modelo de AI21", | 392 | "AI21 Model": "Modelo de AI21", |
| 393 | "MakerSuite API Key": "Clave API de MakerSuite", | 393 | "Google AI Studio API Key": "Clave API de Google AI Studio", |
| 394 | "Google Model": "Modelo de Google", | 394 | "Google Model": "Modelo de Google", |
| 395 | "MistralAI API Key": "Clave API de MistralAI", | 395 | "MistralAI API Key": "Clave API de MistralAI", |
| 396 | "MistralAI Model": "Modelo MistralAI", | 396 | "MistralAI Model": "Modelo MistralAI", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "Méthode alternative", | 390 | "Alt Method": "Méthode alternative", |
| 391 | "AI21 API Key": "Clé API AI21", | 391 | "AI21 API Key": "Clé API AI21", |
| 392 | "AI21 Model": "Modèle AI21", | 392 | "AI21 Model": "Modèle AI21", |
| 393 | "MakerSuite API Key": "Clé API MakerSuite", | 393 | "Google AI Studio API Key": "Clé API Google AI Studio", |
| 394 | "Google Model": "Modèle Google", | 394 | "Google Model": "Modèle Google", |
| 395 | "MistralAI API Key": "Clé API MistralAI", | 395 | "MistralAI API Key": "Clé API MistralAI", |
| 396 | "MistralAI Model": "Modèle MistralAI", | 396 | "MistralAI Model": "Modèle MistralAI", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "Aðferð Bakmenn", | 390 | "Alt Method": "Aðferð Bakmenn", |
| 391 | "AI21 API Key": "Lykill API fyrir AI21", | 391 | "AI21 API Key": "Lykill API fyrir AI21", |
| 392 | "AI21 Model": "AI21 Módel", | 392 | "AI21 Model": "AI21 Módel", |
| 393 | "MakerSuite API Key": "MakerSuite API lykill", | 393 | "Google AI Studio API Key": "Google AI Studio API lykill", |
| 394 | "Google Model": "Google líkan", | 394 | "Google Model": "Google líkan", |
| 395 | "MistralAI API Key": "MistralAI API lykill", | 395 | "MistralAI API Key": "MistralAI API lykill", |
| 396 | "MistralAI Model": "MistralAI líkan", | 396 | "MistralAI Model": "MistralAI líkan", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "Metodo alternativo", | 390 | "Alt Method": "Metodo alternativo", |
| 391 | "AI21 API Key": "Chiave API di AI21", | 391 | "AI21 API Key": "Chiave API di AI21", |
| 392 | "AI21 Model": "Modello AI21", | 392 | "AI21 Model": "Modello AI21", |
| 393 | "MakerSuite API Key": "Chiave API MakerSuite", | 393 | "Google AI Studio API Key": "Chiave API Google AI Studio", |
| 394 | "Google Model": "Modello Google", | 394 | "Google Model": "Modello Google", |
| 395 | "MistralAI API Key": "Chiave API MistralAI", | 395 | "MistralAI API Key": "Chiave API MistralAI", |
| 396 | "MistralAI Model": "Modello MistralAI", | 396 | "MistralAI Model": "Modello MistralAI", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "代替手法", | 390 | "Alt Method": "代替手法", |
| 391 | "AI21 API Key": "AI21のAPIキー", | 391 | "AI21 API Key": "AI21のAPIキー", |
| 392 | "AI21 Model": "AI21モデル", | 392 | "AI21 Model": "AI21モデル", |
| 393 | "MakerSuite API Key": "MakerSuite APIキー", | 393 | "Google AI Studio API Key": "Google AI Studio APIキー", |
| 394 | "Google Model": "Google モデル", | 394 | "Google Model": "Google モデル", |
| 395 | "MistralAI API Key": "MistralAI API キー", | 395 | "MistralAI API Key": "MistralAI API キー", |
| 396 | "MistralAI Model": "MistralAI モデル", | 396 | "MistralAI Model": "MistralAI モデル", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "대체 방법", | 390 | "Alt Method": "대체 방법", |
| 391 | "AI21 API Key": "AI21 API 키", | 391 | "AI21 API Key": "AI21 API 키", |
| 392 | "AI21 Model": "AI21 모델", | 392 | "AI21 Model": "AI21 모델", |
| 393 | "MakerSuite API Key": "MakerSuite API 키", | 393 | "Google AI Studio API Key": "Google AI Studio API 키", |
| 394 | "Google Model": "구글 모델", | 394 | "Google Model": "구글 모델", |
| 395 | "MistralAI API Key": "MistralAI API 키", | 395 | "MistralAI API Key": "MistralAI API 키", |
| 396 | "MistralAI Model": "MistralAI 모델", | 396 | "MistralAI Model": "MistralAI 모델", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "Método Alternativo", | 390 | "Alt Method": "Método Alternativo", |
| 391 | "AI21 API Key": "Chave da API AI21", | 391 | "AI21 API Key": "Chave da API AI21", |
| 392 | "AI21 Model": "Modelo AI21", | 392 | "AI21 Model": "Modelo AI21", |
| 393 | "MakerSuite API Key": "Chave API MakerSuite", | 393 | "Google AI Studio API Key": "Chave API Google AI Studio", |
| 394 | "Google Model": "Modelo Google", | 394 | "Google Model": "Modelo Google", |
| 395 | "MistralAI API Key": "Chave de API MistralAI", | 395 | "MistralAI API Key": "Chave de API MistralAI", |
| 396 | "MistralAI Model": "Modelo MistralAI", | 396 | "MistralAI Model": "Modelo MistralAI", |
| @@ -43,7 +43,7 @@ | |||
| 43 | "Smoothing Factor": "Коэффициент сглаживания", | 43 | "Smoothing Factor": "Коэффициент сглаживания", |
| 44 | "No Repeat Ngram Size": "Размер no_repeat_ngram", | 44 | "No Repeat Ngram Size": "Размер no_repeat_ngram", |
| 45 | "Min Length": "Мин. длина", | 45 | "Min Length": "Мин. длина", |
| 46 | "Alternative server URL (leave empty to use the default value).": "Альтернативный URL сервера (оставьте пустым для стандартного значения)", | 46 | "Alternative server URL (leave empty to use the default value).": "URL альтернативного сервера (оставьте пустым для стандартного значения)", |
| 47 | "Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "Удалите свой личный OAI API Key из панели API, и ТОЛЬКО ПОСЛЕ ЭТОГО вводите что-то сюда", | 47 | "Remove your real OAI API Key from the API panel BEFORE typing anything into this box": "Удалите свой личный OAI API Key из панели API, и ТОЛЬКО ПОСЛЕ ЭТОГО вводите что-то сюда", |
| 48 | "We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "Мы не сможем предоставить помощь с проблемами, с которыми вы столкнетесь при использовании неофициальных прокси для OpenAI", | 48 | "We cannot provide support for problems encountered while using an unofficial OpenAI proxy": "Мы не сможем предоставить помощь с проблемами, с которыми вы столкнетесь при использовании неофициальных прокси для OpenAI", |
| 49 | "Context Size (tokens)": "Размер контекста (в токенах)", | 49 | "Context Size (tokens)": "Размер контекста (в токенах)", |
| @@ -186,7 +186,7 @@ | |||
| 186 | "Generate only one line per request": "Генерировать одну строку на запрос", | 186 | "Generate only one line per request": "Генерировать одну строку на запрос", |
| 187 | "Misc. Settings": "Доп. настройки", | 187 | "Misc. Settings": "Доп. настройки", |
| 188 | "Auto-Continue": "Авто-продолжение", | 188 | "Auto-Continue": "Авто-продолжение", |
| 189 | "Collapse Consecutive Newlines": "Сворачивать последовательные новые строки", | 189 | "Collapse Consecutive Newlines": "Сворачивать неск. новых строк в одну", |
| 190 | "Allow for Chat Completion APIs": "Разрешить для Chat Completion API", | 190 | "Allow for Chat Completion APIs": "Разрешить для Chat Completion API", |
| 191 | "Target length (tokens)": "Целевая длина (в токенах)", | 191 | "Target length (tokens)": "Целевая длина (в токенах)", |
| 192 | "World Info": "Информация о мире", | 192 | "World Info": "Информация о мире", |
| @@ -373,7 +373,7 @@ | |||
| 373 | "Prefer Character Card Prompt": "Приоритет промпту из карточки персонажа", | 373 | "Prefer Character Card Prompt": "Приоритет промпту из карточки персонажа", |
| 374 | "Prefer Character Card Jailbreak": "Приоритет джейлбрейку из карточки персонажа", | 374 | "Prefer Character Card Jailbreak": "Приоритет джейлбрейку из карточки персонажа", |
| 375 | "Press Send to continue": "Кнопка отправки продолжает сообщение", | 375 | "Press Send to continue": "Кнопка отправки продолжает сообщение", |
| 376 | "Quick 'Continue' button": "Кнопка быстрого продолжения", | 376 | "Quick 'Continue' button": "Быстрое продолжение", |
| 377 | "Log prompts to console": "Выводить промпты в консоль", | 377 | "Log prompts to console": "Выводить промпты в консоль", |
| 378 | "Never resize avatars": "Не менять размер аватарок", | 378 | "Never resize avatars": "Не менять размер аватарок", |
| 379 | "Show avatar filenames": "Показывать названия файлов аватарок", | 379 | "Show avatar filenames": "Показывать названия файлов аватарок", |
| @@ -495,7 +495,7 @@ | |||
| 495 | "(Write a comma-separated list of tags)": "(Список тегов через запятую)", | 495 | "(Write a comma-separated list of tags)": "(Список тегов через запятую)", |
| 496 | "(A brief description of the personality)": "(Краткое описание личности)", | 496 | "(A brief description of the personality)": "(Краткое описание личности)", |
| 497 | "(Circumstances and context of the interaction)": "(Обстоятельства и контекст этого диалога)", | 497 | "(Circumstances and context of the interaction)": "(Обстоятельства и контекст этого диалога)", |
| 498 | "(Examples of chat dialog. Begin each example with START on a new line.)": "(Примеры диалога. Начинайте каждый пример с START или новой линией.)", | 498 | "(Examples of chat dialog. Begin each example with START on a new line.)": "(Примеры диалога. Начинайте каждый пример с START или новой строкой.)", |
| 499 | "Type here...": "Пишите здесь...", | 499 | "Type here...": "Пишите здесь...", |
| 500 | "Comma separated (required)": "Через запятую (обязательное поле)", | 500 | "Comma separated (required)": "Через запятую (обязательное поле)", |
| 501 | "What this keyword should mean to the AI, sent verbatim": "Что это ключевое слово должно означать для ИИ, отправляется дословно", | 501 | "What this keyword should mean to the AI, sent verbatim": "Что это ключевое слово должно означать для ИИ, отправляется дословно", |
| @@ -552,7 +552,7 @@ | |||
| 552 | "Click to set a new User Name": "Нажмите, чтобы задать новое имя пользователя.", | 552 | "Click to set a new User Name": "Нажмите, чтобы задать новое имя пользователя.", |
| 553 | "Click to lock your selected persona to the current chat. Click again to remove the lock.": "Нажмите, чтобы закрепить выбранную персону для текущего чата. Нажмите еще раз, чтобы открепить.", | 553 | "Click to lock your selected persona to the current chat. Click again to remove the lock.": "Нажмите, чтобы закрепить выбранную персону для текущего чата. Нажмите еще раз, чтобы открепить.", |
| 554 | "Click to set user name for all messages": "Нажмите, чтобы задать имя пользователя для всех сообщений.", | 554 | "Click to set user name for all messages": "Нажмите, чтобы задать имя пользователя для всех сообщений.", |
| 555 | "Create a dummy persona": "Создать персону-болванку", | 555 | "Create a dummy persona": "Создать пустую персону", |
| 556 | "Character Management": "Управление персонажами", | 556 | "Character Management": "Управление персонажами", |
| 557 | "Locked = Character Management panel will stay open": "Закреплено = Панель управление персонажами останется открытой", | 557 | "Locked = Character Management panel will stay open": "Закреплено = Панель управление персонажами останется открытой", |
| 558 | "Select/Create Characters": "Выбрать/Создать персонажа", | 558 | "Select/Create Characters": "Выбрать/Создать персонажа", |
| @@ -625,7 +625,7 @@ | |||
| 625 | "Automatically select a background based on the chat context": "Автоматический выбор фона в зависимости от контекста чата", | 625 | "Automatically select a background based on the chat context": "Автоматический выбор фона в зависимости от контекста чата", |
| 626 | "Filter": "Фильтр", | 626 | "Filter": "Фильтр", |
| 627 | "Exclude message from prompts": "Исключить сообщение из промпта", | 627 | "Exclude message from prompts": "Исключить сообщение из промпта", |
| 628 | "Include message in prompts": "Включить сообщение в подсказки", | 628 | "Include message in prompts": "Включить сообщение в промпт", |
| 629 | "Create checkpoint": "Создать чекпоинт", | 629 | "Create checkpoint": "Создать чекпоинт", |
| 630 | "Create Branch": "Создать ветку", | 630 | "Create Branch": "Создать ветку", |
| 631 | "Embed file or image": "Вставить файл или изображение", | 631 | "Embed file or image": "Вставить файл или изображение", |
| @@ -722,7 +722,7 @@ | |||
| 722 | "Proxy Server URL": "Адрес прокси-сервера", | 722 | "Proxy Server URL": "Адрес прокси-сервера", |
| 723 | "MistralAI Model": "Модель MistralAI", | 723 | "MistralAI Model": "Модель MistralAI", |
| 724 | "MistralAI API Key": "Ключ от API MistralAI", | 724 | "MistralAI API Key": "Ключ от API MistralAI", |
| 725 | "MakerSuite API Key": "Ключ от API MakerSuite", | 725 | "Google AI Studio API Key": "Ключ от API Google AI Studio", |
| 726 | "Google Model": "Модель Google", | 726 | "Google Model": "Модель Google", |
| 727 | "Cohere API Key": "Ключ от API Cohere", | 727 | "Cohere API Key": "Ключ от API Cohere", |
| 728 | "Cohere Model": "Модель Cohere", | 728 | "Cohere Model": "Модель Cohere", |
| @@ -1661,5 +1661,52 @@ | |||
| 1661 | "ext_regex_ai_output_desc": "Сообщения, полученные от API", | 1661 | "ext_regex_ai_output_desc": "Сообщения, полученные от API", |
| 1662 | "ext_regex_sts_desc": "Сообщения, отправленные с помощью команд STscript", | 1662 | "ext_regex_sts_desc": "Сообщения, отправленные с помощью команд STscript", |
| 1663 | "ext_regex_wi_desc": "Содержимое лорбуков и миров. Для работы требует включения флажка \"Только промпт\"!", | 1663 | "ext_regex_wi_desc": "Содержимое лорбуков и миров. Для работы требует включения флажка \"Только промпт\"!", |
| 1664 | "ext_regex_only_format_display_desc": "История чата не изменится, замена будет осуществляться только в отображаемом сообщении (в UI)" | 1664 | "ext_regex_only_format_display_desc": "История чата не изменится, замена будет осуществляться только в отображаемом сообщении (в UI)", |
| 1665 | "Prefer Character Card Instructions": "Приоритет инструкциям из карточек", | ||
| 1666 | "If checked and the character card contains a Post-History Instructions override, use that instead": "Если в карточке персонажа имеется собственная инструкция после истории, в промпт попадёт именно она", | ||
| 1667 | "Auto-select Input Text": "Автовыделение вводимого текста", | ||
| 1668 | "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.": "Автоматически выделять вводимый текст в некоторых текстовых полях при клике/выборе. Работает для вспл. окон и различных кастомных полей ввода.", | ||
| 1669 | "Reset MovingUI panel sizes/locations.": "Сбросить расположение и размеры панелей MovingUI.", | ||
| 1670 | "mui_reset": "Сброс", | ||
| 1671 | "Quick 'Impersonate' button": "Быстрое перевоплощение", | ||
| 1672 | "Show a button in the input area to ask the AI to impersonate your character for a single message": "Показать в поле ввода кнопку, по нажатии на которую ИИ сгенерирует одно сообщение от лица вашего персонажа.", | ||
| 1673 | "Separators as Stop Strings": "Разделители как стоп-строки", | ||
| 1674 | "Names as Stop Strings": "Имена как стоп-строки", | ||
| 1675 | "Add Character and User names to a list of stopping strings.": "Добавлять имена персонажа и пользователя в список стоп-строк.", | ||
| 1676 | "Allow Post-History Instructions": "Разрешить инструкции после истории", | ||
| 1677 | "context_allow_post_history_instructions": "Добавлять в конец промпта инструкции после истории. Работает только при наличии таких инструкций в карточке И при включенной опции ''Приоритет инструкциям из карточек''.\nНЕ РЕКОМЕНДУЕТСЯ ДЛЯ МОДЕЛЕЙ TEXT COMPLETION, МОЖЕТ ПОРТИТЬ ВЫХОДНОЙ ТЕКСТ.", | ||
| 1678 | "First User Prefix": "Первый префикс пользователя", | ||
| 1679 | "Inserted before the first User's message.": "Вставляется перед первым сообщением пользователя.", | ||
| 1680 | "Last User Prefix": "Последний префикс пользователя", | ||
| 1681 | "instruct_last_input_sequence": "Вставляется перед последним сообщением пользователя.", | ||
| 1682 | "Inserted before a User message and as a last prompt line when impersonating.": "Вставляется перед сообщением пользователя в качестве последней строки промпта при перевоплощении.", | ||
| 1683 | "Inserted before a System (added by slash commands or extensions) message.": "Вставляется перед сообщением системы (может быть добавлено слэш-командой или расширением).", | ||
| 1684 | "Load Asset List": "Загрузить список ресурсов", | ||
| 1685 | "Never add character names.": "Не вставлять имя персонажа.", | ||
| 1686 | "Don't add character names unless necessary.": "Вставлять имя персонажа только когда это необходимо.", | ||
| 1687 | "character_names_none": "Не добавлять имена персонажей в качестве префикса. Может повредить качеству ответов в групповых чатах, используйте с осторожностью.", | ||
| 1688 | "Auxiliary": "Вспомогательный", | ||
| 1689 | "Post-History Instructions": "Инструкции после истории", | ||
| 1690 | "Current persona updated": "Текущая персона изменена", | ||
| 1691 | "Your messages will now be sent as ${0}": "Ваши сообщения будут отправляться от лица ${0}", | ||
| 1692 | "Copied!": "Скопировано!", | ||
| 1693 | "Are you sure you want to delete this message?": "Вы точно хотите удалить это сообщение?", | ||
| 1694 | "Delete Message": "Удалить сообщение", | ||
| 1695 | "Delete Swipe": "Удалить свайп", | ||
| 1696 | "Could not get a reply from API. Check your connection settings / API key and try again.": "Не удалось получить ответ от API. Проверьте настройки соединения и API-ключ и повторите попытку.", | ||
| 1697 | "Connecting To Proxy": "Подключение к прокси", | ||
| 1698 | "Are you sure you want to connect to the following proxy URL?": "Вы точно хотите соединиться с прокси по этому адресу?", | ||
| 1699 | "API connection successful!": "Соединение с API установлено!", | ||
| 1700 | "Proxy Saved": "Прокси сохранена", | ||
| 1701 | "Proxy Deleted": "Прокси удалена", | ||
| 1702 | "Could not find proxy with name '${0}'": "Не удалось найти прокси с названием '${0}'", | ||
| 1703 | "Proxy preset '${0}' not found in proxies array.": "Пресет с названием '${0}' не найден в списке прокси.", | ||
| 1704 | "Please wait for the previous request to complete.": "Пожалуйста, дождитесь окончания обработки предыдущего запроса.", | ||
| 1705 | "Start new chat?": "Начать новый чат?", | ||
| 1706 | "If necessary, you can later restore this chat file from the /backups folder": "При необходимости этот чат можно будет восстановить из папки /backups", | ||
| 1707 | "Also delete the current chat file": "Также удалить текущий чат", | ||
| 1708 | "chat_rename_1": "Введите новое имя чата:", | ||
| 1709 | "chat_rename_2": "!!Не используйте имя уже существующего файла, это приведёт к ошибке!!", | ||
| 1710 | "chat_rename_3": "Будут разрушены связи между чатами-чекпоинтами.", | ||
| 1711 | "chat_rename_4": "Расширение '.jsonl' дописывать не нужно." | ||
| 1665 | } | 1712 | } |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "Альтернативний метод", | 390 | "Alt Method": "Альтернативний метод", |
| 391 | "AI21 API Key": "Ключ API для AI21", | 391 | "AI21 API Key": "Ключ API для AI21", |
| 392 | "AI21 Model": "Модель AI21", | 392 | "AI21 Model": "Модель AI21", |
| 393 | "MakerSuite API Key": "Ключ API MakerSuite", | 393 | "Google AI Studio API Key": "Ключ API Google AI Studio", |
| 394 | "Google Model": "Модель Google", | 394 | "Google Model": "Модель Google", |
| 395 | "MistralAI API Key": "Ключ API MistralAI", | 395 | "MistralAI API Key": "Ключ API MistralAI", |
| 396 | "MistralAI Model": "Модель MistralAI", | 396 | "MistralAI Model": "Модель MistralAI", |
| @@ -390,7 +390,7 @@ | |||
| 390 | "Alt Method": "Phương pháp thay thế", | 390 | "Alt Method": "Phương pháp thay thế", |
| 391 | "AI21 API Key": "Khóa API của AI21", | 391 | "AI21 API Key": "Khóa API của AI21", |
| 392 | "AI21 Model": "Mô hình AI21", | 392 | "AI21 Model": "Mô hình AI21", |
| 393 | "MakerSuite API Key": "Khóa API MakerSuite", | 393 | "Google AI Studio API Key": "Khóa API Google AI Studio", |
| 394 | "Google Model": "Mô hình Google", | 394 | "Google Model": "Mô hình Google", |
| 395 | "MistralAI API Key": "Khóa API MistralAI", | 395 | "MistralAI API Key": "Khóa API MistralAI", |
| 396 | "MistralAI Model": "Mô hình MistralAI", | 396 | "MistralAI Model": "Mô hình MistralAI", |
| @@ -406,7 +406,7 @@ | |||
| 406 | "Alt Method": "备用方法", | 406 | "Alt Method": "备用方法", |
| 407 | "AI21 API Key": "AI21 API 密钥", | 407 | "AI21 API Key": "AI21 API 密钥", |
| 408 | "AI21 Model": "AI21 模型", | 408 | "AI21 Model": "AI21 模型", |
| 409 | "MakerSuite API Key": "MakerSuite API 密钥", | 409 | "Google AI Studio API Key": "Google AI Studio API 密钥", |
| 410 | "Google Model": "Google 模型", | 410 | "Google Model": "Google 模型", |
| 411 | "MistralAI API Key": "MistralAI API 密钥", | 411 | "MistralAI API Key": "MistralAI API 密钥", |
| 412 | "MistralAI Model": "MistralAI 模型", | 412 | "MistralAI Model": "MistralAI 模型", |
| @@ -391,7 +391,7 @@ | |||
| 391 | "Alt Method": "替代方法", | 391 | "Alt Method": "替代方法", |
| 392 | "AI21 API Key": "AI21 API 金鑰", | 392 | "AI21 API Key": "AI21 API 金鑰", |
| 393 | "AI21 Model": "AI21 模型", | 393 | "AI21 Model": "AI21 模型", |
| 394 | "MakerSuite API Key": "MakerSuite API 金鑰", | 394 | "Google AI Studio API Key": "Google AI Studio API 金鑰", |
| 395 | "Google Model": "Google 模型", | 395 | "Google Model": "Google 模型", |
| 396 | "MistralAI API Key": "MistralAI API 金鑰", | 396 | "MistralAI API Key": "MistralAI API 金鑰", |
| 397 | "MistralAI Model": "MistralAI 模型", | 397 | "MistralAI Model": "MistralAI 模型", |
| @@ -84,6 +84,7 @@ import { | |||
| 84 | context_presets, | 84 | context_presets, |
| 85 | resetMovableStyles, | 85 | resetMovableStyles, |
| 86 | forceCharacterEditorTokenize, | 86 | forceCharacterEditorTokenize, |
| 87 | applyPowerUserSettings, | ||
| 87 | } from './scripts/power-user.js'; | 88 | } from './scripts/power-user.js'; |
| 88 | 89 | ||
| 89 | import { | 90 | import { |
| @@ -242,7 +243,7 @@ import { DragAndDropHandler } from './scripts/dragdrop.js'; | |||
| 242 | import { INTERACTABLE_CONTROL_CLASS, initKeyboard } from './scripts/keyboard.js'; | 243 | import { INTERACTABLE_CONTROL_CLASS, initKeyboard } from './scripts/keyboard.js'; |
| 243 | import { initDynamicStyles } from './scripts/dynamic-styles.js'; | 244 | import { initDynamicStyles } from './scripts/dynamic-styles.js'; |
| 244 | import { SlashCommandEnumValue, enumTypes } from './scripts/slash-commands/SlashCommandEnumValue.js'; | 245 | import { SlashCommandEnumValue, enumTypes } from './scripts/slash-commands/SlashCommandEnumValue.js'; |
| 245 | import { enumIcons } from './scripts/slash-commands/SlashCommandCommonEnumsProvider.js'; | 246 | import { commonEnumProviders, enumIcons } from './scripts/slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 246 | 247 | ||
| 247 | //exporting functions and vars for mods | 248 | //exporting functions and vars for mods |
| 248 | export { | 249 | export { |
| @@ -415,6 +416,7 @@ export const event_types = { | |||
| 415 | GENERATION_STOPPED: 'generation_stopped', | 416 | GENERATION_STOPPED: 'generation_stopped', |
| 416 | GENERATION_ENDED: 'generation_ended', | 417 | GENERATION_ENDED: 'generation_ended', |
| 417 | EXTENSIONS_FIRST_LOAD: 'extensions_first_load', | 418 | EXTENSIONS_FIRST_LOAD: 'extensions_first_load', |
| 419 | EXTENSION_SETTINGS_LOADED: 'extension_settings_loaded', | ||
| 418 | SETTINGS_LOADED: 'settings_loaded', | 420 | SETTINGS_LOADED: 'settings_loaded', |
| 419 | SETTINGS_UPDATED: 'settings_updated', | 421 | SETTINGS_UPDATED: 'settings_updated', |
| 420 | GROUP_UPDATED: 'group_updated', | 422 | GROUP_UPDATED: 'group_updated', |
| @@ -486,14 +488,6 @@ let default_user_name = 'User'; | |||
| 486 | export let name1 = default_user_name; | 488 | export let name1 = default_user_name; |
| 487 | export let name2 = 'SillyTavern System'; | 489 | export let name2 = 'SillyTavern System'; |
| 488 | export let chat = []; | 490 | export let chat = []; |
| 489 | let safetychat = [ | ||
| 490 | { | ||
| 491 | name: systemUserName, | ||
| 492 | is_user: false, | ||
| 493 | create_date: 0, | ||
| 494 | mes: 'You deleted a character/chat and arrived back here for safety reasons! Pick another character!', | ||
| 495 | }, | ||
| 496 | ]; | ||
| 497 | let chatSaveTimeout; | 491 | let chatSaveTimeout; |
| 498 | let importFlashTimeout; | 492 | let importFlashTimeout; |
| 499 | export let isChatSaving = false; | 493 | export let isChatSaving = false; |
| @@ -592,6 +586,17 @@ export const extension_prompt_roles = { | |||
| 592 | 586 | ||
| 593 | export const MAX_INJECTION_DEPTH = 1000; | 587 | export const MAX_INJECTION_DEPTH = 1000; |
| 594 | 588 | ||
| 589 | const SAFETY_CHAT = [ | ||
| 590 | { | ||
| 591 | name: systemUserName, | ||
| 592 | force_avatar: system_avatar, | ||
| 593 | is_system: true, | ||
| 594 | is_user: false, | ||
| 595 | create_date: 0, | ||
| 596 | mes: 'You deleted a character/chat and arrived back here for safety reasons! Pick another character!', | ||
| 597 | }, | ||
| 598 | ]; | ||
| 599 | |||
| 595 | export let system_messages = {}; | 600 | export let system_messages = {}; |
| 596 | 601 | ||
| 597 | async function getSystemMessages() { | 602 | async function getSystemMessages() { |
| @@ -1879,7 +1884,12 @@ export function messageFormatting(mes, ch_name, isSystem, isUser, messageId) { | |||
| 1879 | } | 1884 | } |
| 1880 | 1885 | ||
| 1881 | if (Number(messageId) === 0 && !isSystem && !isUser) { | 1886 | if (Number(messageId) === 0 && !isSystem && !isUser) { |
| 1887 | const mesBeforeReplace = mes; | ||
| 1888 | const chatMessage = chat[messageId]; | ||
| 1882 | mes = substituteParams(mes, undefined, ch_name); | 1889 | mes = substituteParams(mes, undefined, ch_name); |
| 1890 | if (chatMessage && chatMessage.mes === mesBeforeReplace && chatMessage.extra?.display_text !== mesBeforeReplace) { | ||
| 1891 | chatMessage.mes = mes; | ||
| 1892 | } | ||
| 1883 | } | 1893 | } |
| 1884 | 1894 | ||
| 1885 | mesForShowdownParse = mes; | 1895 | mesForShowdownParse = mes; |
| @@ -2185,7 +2195,7 @@ export function addCopyToCodeBlocks(messageElement) { | |||
| 2185 | codeBlocks.get(i).appendChild(copyButton); | 2195 | codeBlocks.get(i).appendChild(copyButton); |
| 2186 | copyButton.addEventListener('pointerup', function (event) { | 2196 | copyButton.addEventListener('pointerup', function (event) { |
| 2187 | navigator.clipboard.writeText(codeBlocks.get(i).innerText); | 2197 | navigator.clipboard.writeText(codeBlocks.get(i).innerText); |
| 2188 | toastr.info('Copied!', '', { timeOut: 2000 }); | 2198 | toastr.info(t`Copied!`, '', { timeOut: 2000 }); |
| 2189 | }); | 2199 | }); |
| 2190 | } | 2200 | } |
| 2191 | } | 2201 | } |
| @@ -2698,7 +2708,7 @@ function addPersonaDescriptionExtensionPrompt() { | |||
| 2698 | const INJECT_TAG = 'PERSONA_DESCRIPTION'; | 2708 | const INJECT_TAG = 'PERSONA_DESCRIPTION'; |
| 2699 | setExtensionPrompt(INJECT_TAG, '', extension_prompt_types.IN_PROMPT, 0); | 2709 | setExtensionPrompt(INJECT_TAG, '', extension_prompt_types.IN_PROMPT, 0); |
| 2700 | 2710 | ||
| 2701 | if (!power_user.persona_description) { | 2711 | if (!power_user.persona_description || power_user.persona_description_position === persona_description_positions.NONE) { |
| 2702 | return; | 2712 | return; |
| 2703 | } | 2713 | } |
| 2704 | 2714 | ||
| @@ -2819,7 +2829,7 @@ export function getCharacterCardFields() { | |||
| 2819 | } | 2829 | } |
| 2820 | 2830 | ||
| 2821 | export function isStreamingEnabled() { | 2831 | export function isStreamingEnabled() { |
| 2822 | const noStreamSources = [chat_completion_sources.SCALE, chat_completion_sources.AI21]; | 2832 | const noStreamSources = [chat_completion_sources.SCALE]; |
| 2823 | return ((main_api == 'openai' && oai_settings.stream_openai && !noStreamSources.includes(oai_settings.chat_completion_source) && !(oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE && oai_settings.google_model.includes('bison'))) | 2833 | return ((main_api == 'openai' && oai_settings.stream_openai && !noStreamSources.includes(oai_settings.chat_completion_source) && !(oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE && oai_settings.google_model.includes('bison'))) |
| 2824 | || (main_api == 'kobold' && kai_settings.streaming_kobold && kai_flags.can_use_streaming) | 2834 | || (main_api == 'kobold' && kai_settings.streaming_kobold && kai_flags.can_use_streaming) |
| 2825 | || (main_api == 'novel' && nai_settings.streaming_novel) | 2835 | || (main_api == 'novel' && nai_settings.streaming_novel) |
| @@ -2839,7 +2849,14 @@ function hideStopButton() { | |||
| 2839 | } | 2849 | } |
| 2840 | 2850 | ||
| 2841 | class StreamingProcessor { | 2851 | class StreamingProcessor { |
| 2842 | constructor(type, force_name2, timeStarted, messageAlreadyGenerated) { | 2852 | /** |
| 2853 | * Creates a new streaming processor. | ||
| 2854 | * @param {string} type Generation type | ||
| 2855 | * @param {boolean} forceName2 If true, force the use of name2 | ||
| 2856 | * @param {Date} timeStarted Date when generation was started | ||
| 2857 | * @param {string} continueMessage Previous message if the type is 'continue' | ||
| 2858 | */ | ||
| 2859 | constructor(type, forceName2, timeStarted, continueMessage) { | ||
| 2843 | this.result = ''; | 2860 | this.result = ''; |
| 2844 | this.messageId = -1; | 2861 | this.messageId = -1; |
| 2845 | this.messageDom = null; | 2862 | this.messageDom = null; |
| @@ -2849,14 +2866,14 @@ class StreamingProcessor { | |||
| 2849 | /** @type {HTMLTextAreaElement} */ | 2866 | /** @type {HTMLTextAreaElement} */ |
| 2850 | this.sendTextarea = document.querySelector('#send_textarea'); | 2867 | this.sendTextarea = document.querySelector('#send_textarea'); |
| 2851 | this.type = type; | 2868 | this.type = type; |
| 2852 | this.force_name2 = force_name2; | 2869 | this.force_name2 = forceName2; |
| 2853 | this.isStopped = false; | 2870 | this.isStopped = false; |
| 2854 | this.isFinished = false; | 2871 | this.isFinished = false; |
| 2855 | this.generator = this.nullStreamingGeneration; | 2872 | this.generator = this.nullStreamingGeneration; |
| 2856 | this.abortController = new AbortController(); | 2873 | this.abortController = new AbortController(); |
| 2857 | this.firstMessageText = '...'; | 2874 | this.firstMessageText = '...'; |
| 2858 | this.timeStarted = timeStarted; | 2875 | this.timeStarted = timeStarted; |
| 2859 | this.messageAlreadyGenerated = messageAlreadyGenerated; | 2876 | this.continueMessage = type === 'continue' ? continueMessage : ''; |
| 2860 | this.swipes = []; | 2877 | this.swipes = []; |
| 2861 | /** @type {import('./scripts/logprobs.js').TokenLogprobs[]} */ | 2878 | /** @type {import('./scripts/logprobs.js').TokenLogprobs[]} */ |
| 2862 | this.messageLogprobs = []; | 2879 | this.messageLogprobs = []; |
| @@ -3009,8 +3026,7 @@ class StreamingProcessor { | |||
| 3009 | await eventSource.emit(event_types.IMPERSONATE_READY, text); | 3026 | await eventSource.emit(event_types.IMPERSONATE_READY, text); |
| 3010 | } | 3027 | } |
| 3011 | 3028 | ||
| 3012 | const continueMsg = this.type === 'continue' ? this.messageAlreadyGenerated : undefined; | 3029 | saveLogprobsForActiveMessage(this.messageLogprobs.filter(Boolean), this.continueMessage); |
| 3013 | saveLogprobsForActiveMessage(this.messageLogprobs.filter(Boolean), continueMsg); | ||
| 3014 | await saveChatConditional(); | 3030 | await saveChatConditional(); |
| 3015 | unblockGeneration(); | 3031 | unblockGeneration(); |
| 3016 | generatedPromptCache = ''; | 3032 | generatedPromptCache = ''; |
| @@ -3106,7 +3122,7 @@ class StreamingProcessor { | |||
| 3106 | if (logprobs) { | 3122 | if (logprobs) { |
| 3107 | this.messageLogprobs.push(...(Array.isArray(logprobs) ? logprobs : [logprobs])); | 3123 | this.messageLogprobs.push(...(Array.isArray(logprobs) ? logprobs : [logprobs])); |
| 3108 | } | 3124 | } |
| 3109 | await sw.tick(() => this.onProgressStreaming(this.messageId, this.messageAlreadyGenerated + text)); | 3125 | await sw.tick(() => this.onProgressStreaming(this.messageId, this.continueMessage + text)); |
| 3110 | } | 3126 | } |
| 3111 | const seconds = (timestamps[timestamps.length - 1] - timestamps[0]) / 1000; | 3127 | const seconds = (timestamps[timestamps.length - 1] - timestamps[0]) / 1000; |
| 3112 | console.warn(`Stream stats: ${timestamps.length} tokens, ${seconds.toFixed(2)} seconds, rate: ${Number(timestamps.length / seconds).toFixed(2)} TPS`); | 3128 | console.warn(`Stream stats: ${timestamps.length} tokens, ${seconds.toFixed(2)} seconds, rate: ${Number(timestamps.length / seconds).toFixed(2)} TPS`); |
| @@ -3299,8 +3315,6 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3299 | const isInstruct = power_user.instruct.enabled && main_api !== 'openai'; | 3315 | const isInstruct = power_user.instruct.enabled && main_api !== 'openai'; |
| 3300 | const isImpersonate = type == 'impersonate'; | 3316 | const isImpersonate = type == 'impersonate'; |
| 3301 | 3317 | ||
| 3302 | let message_already_generated = isImpersonate ? `${name1}: ` : `${name2}: `; | ||
| 3303 | |||
| 3304 | if (!(dryRun || type == 'regenerate' || type == 'swipe' || type == 'quiet')) { | 3318 | if (!(dryRun || type == 'regenerate' || type == 'swipe' || type == 'quiet')) { |
| 3305 | const interruptedByCommand = await processCommands(String($('#send_textarea').val())); | 3319 | const interruptedByCommand = await processCommands(String($('#send_textarea').val())); |
| 3306 | 3320 | ||
| @@ -3715,7 +3729,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3715 | const storyStringParams = { | 3729 | const storyStringParams = { |
| 3716 | description: description, | 3730 | description: description, |
| 3717 | personality: personality, | 3731 | personality: personality, |
| 3718 | persona: persona, | 3732 | persona: power_user.persona_description_position == persona_description_positions.IN_PROMPT ? persona : '', |
| 3719 | scenario: scenario, | 3733 | scenario: scenario, |
| 3720 | system: isInstruct ? system : '', | 3734 | system: isInstruct ? system : '', |
| 3721 | char: name2, | 3735 | char: name2, |
| @@ -3739,7 +3753,6 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3739 | let oaiMessageExamples = []; | 3753 | let oaiMessageExamples = []; |
| 3740 | 3754 | ||
| 3741 | if (main_api === 'openai') { | 3755 | if (main_api === 'openai') { |
| 3742 | message_already_generated = ''; | ||
| 3743 | oaiMessages = setOpenAIMessages(coreChat); | 3756 | oaiMessages = setOpenAIMessages(coreChat); |
| 3744 | oaiMessageExamples = setOpenAIMessageExamples(mesExamplesArray); | 3757 | oaiMessageExamples = setOpenAIMessageExamples(mesExamplesArray); |
| 3745 | } | 3758 | } |
| @@ -3750,7 +3763,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3750 | } | 3763 | } |
| 3751 | 3764 | ||
| 3752 | let examplesString = ''; | 3765 | let examplesString = ''; |
| 3753 | let chatString = ''; | 3766 | let chatString = addChatsPreamble(addChatsSeparator('')); |
| 3754 | let cyclePrompt = ''; | 3767 | let cyclePrompt = ''; |
| 3755 | 3768 | ||
| 3756 | async function getMessagesTokenCount() { | 3769 | async function getMessagesTokenCount() { |
| @@ -3759,10 +3772,10 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3759 | storyString, | 3772 | storyString, |
| 3760 | afterScenarioAnchor, | 3773 | afterScenarioAnchor, |
| 3761 | examplesString, | 3774 | examplesString, |
| 3775 | userAlignmentMessage, | ||
| 3762 | chatString, | 3776 | chatString, |
| 3763 | quiet_prompt, | 3777 | modifyLastPromptLine(''), |
| 3764 | cyclePrompt, | 3778 | cyclePrompt, |
| 3765 | userAlignmentMessage, | ||
| 3766 | ].join('').replace(/\r/gm, ''); | 3779 | ].join('').replace(/\r/gm, ''); |
| 3767 | return getTokenCountAsync(encodeString, power_user.token_padding); | 3780 | return getTokenCountAsync(encodeString, power_user.token_padding); |
| 3768 | } | 3781 | } |
| @@ -3793,8 +3806,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3793 | } | 3806 | } |
| 3794 | 3807 | ||
| 3795 | tokenCount += await getTokenCountAsync(item.replace(/\r/gm, '')); | 3808 | tokenCount += await getTokenCountAsync(item.replace(/\r/gm, '')); |
| 3796 | chatString = item + chatString; | ||
| 3797 | if (tokenCount < this_max_context) { | 3809 | if (tokenCount < this_max_context) { |
| 3810 | chatString = chatString + item; | ||
| 3798 | arrMes[index] = item; | 3811 | arrMes[index] = item; |
| 3799 | lastAddedIndex = Math.max(lastAddedIndex, index); | 3812 | lastAddedIndex = Math.max(lastAddedIndex, index); |
| 3800 | } else { | 3813 | } else { |
| @@ -3820,8 +3833,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3820 | } | 3833 | } |
| 3821 | 3834 | ||
| 3822 | tokenCount += await getTokenCountAsync(item.replace(/\r/gm, '')); | 3835 | tokenCount += await getTokenCountAsync(item.replace(/\r/gm, '')); |
| 3823 | chatString = item + chatString; | ||
| 3824 | if (tokenCount < this_max_context) { | 3836 | if (tokenCount < this_max_context) { |
| 3837 | chatString = chatString + item; | ||
| 3825 | arrMes[i] = item; | 3838 | arrMes[i] = item; |
| 3826 | lastAddedIndex = Math.max(lastAddedIndex, i); | 3839 | lastAddedIndex = Math.max(lastAddedIndex, i); |
| 3827 | } else { | 3840 | } else { |
| @@ -3882,7 +3895,6 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3882 | cyclePrompt += oai_settings.continue_postfix; | 3895 | cyclePrompt += oai_settings.continue_postfix; |
| 3883 | continue_mag += oai_settings.continue_postfix; | 3896 | continue_mag += oai_settings.continue_postfix; |
| 3884 | } | 3897 | } |
| 3885 | message_already_generated = continue_mag; | ||
| 3886 | } | 3898 | } |
| 3887 | 3899 | ||
| 3888 | const originalType = type; | 3900 | const originalType = type; |
| @@ -4019,15 +4031,16 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4019 | async function checkPromptSize() { | 4031 | async function checkPromptSize() { |
| 4020 | console.debug('---checking Prompt size'); | 4032 | console.debug('---checking Prompt size'); |
| 4021 | setPromptString(); | 4033 | setPromptString(); |
| 4034 | const jointMessages = mesSend.map((e) => `${e.extensionPrompts.join('')}${e.message}`).join(''); | ||
| 4022 | const prompt = [ | 4035 | const prompt = [ |
| 4023 | beforeScenarioAnchor, | 4036 | beforeScenarioAnchor, |
| 4024 | storyString, | 4037 | storyString, |
| 4025 | afterScenarioAnchor, | 4038 | afterScenarioAnchor, |
| 4026 | mesExmString, | 4039 | mesExmString, |
| 4027 | mesSend.map((e) => `${e.extensionPrompts.join('')}${e.message}`).join(''), | 4040 | addChatsPreamble(addChatsSeparator(jointMessages)), |
| 4028 | '\n', | 4041 | '\n', |
| 4042 | modifyLastPromptLine(''), | ||
| 4029 | generatedPromptCache, | 4043 | generatedPromptCache, |
| 4030 | quiet_prompt, | ||
| 4031 | ].join('').replace(/\r/gm, ''); | 4044 | ].join('').replace(/\r/gm, ''); |
| 4032 | let thisPromptContextSize = await getTokenCountAsync(prompt, power_user.token_padding); | 4045 | let thisPromptContextSize = await getTokenCountAsync(prompt, power_user.token_padding); |
| 4033 | 4046 | ||
| @@ -4293,7 +4306,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4293 | padding: power_user.token_padding, | 4306 | padding: power_user.token_padding, |
| 4294 | main_api: main_api, | 4307 | main_api: main_api, |
| 4295 | instruction: isInstruct ? substituteParams(power_user.prefer_character_prompt && system ? system : power_user.instruct.system_prompt) : '', | 4308 | instruction: isInstruct ? substituteParams(power_user.prefer_character_prompt && system ? system : power_user.instruct.system_prompt) : '', |
| 4296 | userPersona: (power_user.persona_description || ''), | 4309 | userPersona: (power_user.persona_description_position == persona_description_positions.IN_PROMPT ? (persona || '') : ''), |
| 4297 | }; | 4310 | }; |
| 4298 | 4311 | ||
| 4299 | //console.log(additionalPromptStuff); | 4312 | //console.log(additionalPromptStuff); |
| @@ -4309,7 +4322,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4309 | console.debug(`pushed prompt bits to itemizedPrompts array. Length is now: ${itemizedPrompts.length}`); | 4322 | console.debug(`pushed prompt bits to itemizedPrompts array. Length is now: ${itemizedPrompts.length}`); |
| 4310 | 4323 | ||
| 4311 | if (isStreamingEnabled() && type !== 'quiet') { | 4324 | if (isStreamingEnabled() && type !== 'quiet') { |
| 4312 | streamingProcessor = new StreamingProcessor(type, force_name2, generation_started, message_already_generated); | 4325 | streamingProcessor = new StreamingProcessor(type, force_name2, generation_started, continue_mag); |
| 4313 | if (isContinue) { | 4326 | if (isContinue) { |
| 4314 | // Save reply does add cycle text to the prompt, so it's not needed here | 4327 | // Save reply does add cycle text to the prompt, so it's not needed here |
| 4315 | streamingProcessor.firstMessageText = ''; | 4328 | streamingProcessor.firstMessageText = ''; |
| @@ -5071,7 +5084,7 @@ async function promptItemize(itemizedPrompts, requestedMesId) { | |||
| 5071 | } | 5084 | } |
| 5072 | 5085 | ||
| 5073 | navigator.clipboard.writeText(rawPromptValues); | 5086 | navigator.clipboard.writeText(rawPromptValues); |
| 5074 | toastr.info('Copied!'); | 5087 | toastr.info(t`Copied!`); |
| 5075 | }); | 5088 | }); |
| 5076 | 5089 | ||
| 5077 | popup.dlg.querySelector('#showRawPrompt').addEventListener('click', function () { | 5090 | popup.dlg.querySelector('#showRawPrompt').addEventListener('click', function () { |
| @@ -5337,17 +5350,10 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc | |||
| 5337 | // Regex uses vars, so add before formatting | 5350 | // Regex uses vars, so add before formatting |
| 5338 | getMessage = getRegexedString(getMessage, isImpersonate ? regex_placement.USER_INPUT : regex_placement.AI_OUTPUT); | 5351 | getMessage = getRegexedString(getMessage, isImpersonate ? regex_placement.USER_INPUT : regex_placement.AI_OUTPUT); |
| 5339 | 5352 | ||
| 5340 | if (!displayIncompleteSentences && power_user.trim_sentences) { | ||
| 5341 | getMessage = trimToEndSentence(getMessage, power_user.include_newline); | ||
| 5342 | } | ||
| 5343 | |||
| 5344 | if (power_user.collapse_newlines) { | 5353 | if (power_user.collapse_newlines) { |
| 5345 | getMessage = collapseNewlines(getMessage); | 5354 | getMessage = collapseNewlines(getMessage); |
| 5346 | } | 5355 | } |
| 5347 | 5356 | ||
| 5348 | if (power_user.trim_spaces) { | ||
| 5349 | getMessage = getMessage.trim(); | ||
| 5350 | } | ||
| 5351 | // trailing invisible whitespace before every newlines, on a multiline string | 5357 | // trailing invisible whitespace before every newlines, on a multiline string |
| 5352 | // "trailing whitespace on newlines \nevery line of the string \n?sample text" -> | 5358 | // "trailing whitespace on newlines \nevery line of the string \n?sample text" -> |
| 5353 | // "trailing whitespace on newlines\nevery line of the string\nsample text" | 5359 | // "trailing whitespace on newlines\nevery line of the string\nsample text" |
| @@ -5439,6 +5445,14 @@ export function cleanUpMessage(getMessage, isImpersonate, isContinue, displayInc | |||
| 5439 | getMessage = getMessage.trim(); | 5445 | getMessage = getMessage.trim(); |
| 5440 | } | 5446 | } |
| 5441 | 5447 | ||
| 5448 | if (!displayIncompleteSentences && power_user.trim_sentences) { | ||
| 5449 | getMessage = trimToEndSentence(getMessage, power_user.include_newline); | ||
| 5450 | } | ||
| 5451 | |||
| 5452 | if (power_user.trim_spaces) { | ||
| 5453 | getMessage = getMessage.trim(); | ||
| 5454 | } | ||
| 5455 | |||
| 5442 | return getMessage; | 5456 | return getMessage; |
| 5443 | } | 5457 | } |
| 5444 | 5458 | ||
| @@ -5669,7 +5683,7 @@ export function resetChatState() { | |||
| 5669 | // replaces deleted charcter name with system user since it will be displayed next. | 5683 | // replaces deleted charcter name with system user since it will be displayed next. |
| 5670 | name2 = systemUserName; | 5684 | name2 = systemUserName; |
| 5671 | // sets up system user to tell user about having deleted a character | 5685 | // sets up system user to tell user about having deleted a character |
| 5672 | chat = [...safetychat]; | 5686 | chat.splice(0, chat.length, ...SAFETY_CHAT); |
| 5673 | // resets chat metadata | 5687 | // resets chat metadata |
| 5674 | chat_metadata = {}; | 5688 | chat_metadata = {}; |
| 5675 | // resets the characters array, forcing getcharacters to reset | 5689 | // resets the characters array, forcing getcharacters to reset |
| @@ -6300,7 +6314,7 @@ export function setUserName(value) { | |||
| 6300 | console.log(`User name changed to ${name1}`); | 6314 | console.log(`User name changed to ${name1}`); |
| 6301 | $('#your_name').val(name1); | 6315 | $('#your_name').val(name1); |
| 6302 | if (power_user.persona_show_notifications) { | 6316 | if (power_user.persona_show_notifications) { |
| 6303 | toastr.success(`Your messages will now be sent as ${name1}`, 'Current persona updated'); | 6317 | toastr.success(t`Your messages will now be sent as ${name1}`, t`Current persona updated`); |
| 6304 | } | 6318 | } |
| 6305 | saveSettingsDebounced(); | 6319 | saveSettingsDebounced(); |
| 6306 | } | 6320 | } |
| @@ -6452,6 +6466,8 @@ export async function getSettings() { | |||
| 6452 | // Load power user settings | 6466 | // Load power user settings |
| 6453 | await loadPowerUserSettings(settings, data); | 6467 | await loadPowerUserSettings(settings, data); |
| 6454 | 6468 | ||
| 6469 | applyPowerUserSettings(); | ||
| 6470 | |||
| 6455 | // Load character tags | 6471 | // Load character tags |
| 6456 | loadTagsSettings(settings); | 6472 | loadTagsSettings(settings); |
| 6457 | 6473 | ||
| @@ -6506,9 +6522,10 @@ export async function getSettings() { | |||
| 6506 | selected_button = settings.selected_button; | 6522 | selected_button = settings.selected_button; |
| 6507 | 6523 | ||
| 6508 | if (data.enable_extensions) { | 6524 | if (data.enable_extensions) { |
| 6525 | const enableAutoUpdate = Boolean(data.enable_extensions_auto_update); | ||
| 6509 | const isVersionChanged = settings.currentVersion !== currentVersion; | 6526 | const isVersionChanged = settings.currentVersion !== currentVersion; |
| 6510 | await loadExtensionSettings(settings, isVersionChanged); | 6527 | await loadExtensionSettings(settings, isVersionChanged, enableAutoUpdate); |
| 6511 | eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED); | 6528 | await eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED); |
| 6512 | } | 6529 | } |
| 6513 | 6530 | ||
| 6514 | firstRun = !!settings.firstRun; | 6531 | firstRun = !!settings.firstRun; |
| @@ -8379,6 +8396,12 @@ const CONNECT_API_MAP = { | |||
| 8379 | button: '#api_button_openai', | 8396 | button: '#api_button_openai', |
| 8380 | source: chat_completion_sources.OPENAI, | 8397 | source: chat_completion_sources.OPENAI, |
| 8381 | }, | 8398 | }, |
| 8399 | // Google alias | ||
| 8400 | 'google': { | ||
| 8401 | selected: 'openai', | ||
| 8402 | button: '#api_button_openai', | ||
| 8403 | source: chat_completion_sources.MAKERSUITE, | ||
| 8404 | }, | ||
| 8382 | // OpenRouter special naming, to differentiate between chat comp and text comp | 8405 | // OpenRouter special naming, to differentiate between chat comp and text comp |
| 8383 | 'openrouter': { | 8406 | 'openrouter': { |
| 8384 | selected: 'openai', | 8407 | selected: 'openai', |
| @@ -8464,7 +8487,7 @@ async function disableInstructCallback() { | |||
| 8464 | /** | 8487 | /** |
| 8465 | * @param {string} text API name | 8488 | * @param {string} text API name |
| 8466 | */ | 8489 | */ |
| 8467 | async function connectAPISlash(_, text) { | 8490 | async function connectAPISlash(args, text) { |
| 8468 | if (!text.trim()) { | 8491 | if (!text.trim()) { |
| 8469 | for (const [key, config] of Object.entries(CONNECT_API_MAP)) { | 8492 | for (const [key, config] of Object.entries(CONNECT_API_MAP)) { |
| 8470 | if (config.selected !== main_api) continue; | 8493 | if (config.selected !== main_api) continue; |
| @@ -8487,12 +8510,15 @@ async function connectAPISlash(_, text) { | |||
| 8487 | 8510 | ||
| 8488 | return key; | 8511 | return key; |
| 8489 | } | 8512 | } |
| 8513 | |||
| 8514 | console.error('FIXME: The current API is not in the API map'); | ||
| 8515 | return ''; | ||
| 8490 | } | 8516 | } |
| 8491 | 8517 | ||
| 8492 | const apiConfig = CONNECT_API_MAP[text.toLowerCase()]; | 8518 | const apiConfig = CONNECT_API_MAP[text.toLowerCase()]; |
| 8493 | if (!apiConfig) { | 8519 | if (!apiConfig) { |
| 8494 | toastr.error(`Error: ${text} is not a valid API`); | 8520 | toastr.error(`Error: ${text} is not a valid API`); |
| 8495 | return; | 8521 | return ''; |
| 8496 | } | 8522 | } |
| 8497 | 8523 | ||
| 8498 | $(`#main_api option[value='${apiConfig.selected || text}']`).prop('selected', true); | 8524 | $(`#main_api option[value='${apiConfig.selected || text}']`).prop('selected', true); |
| @@ -8512,14 +8538,18 @@ async function connectAPISlash(_, text) { | |||
| 8512 | $(apiConfig.button).trigger('click'); | 8538 | $(apiConfig.button).trigger('click'); |
| 8513 | } | 8539 | } |
| 8514 | 8540 | ||
| 8515 | toastr.info(`API set to ${text}, trying to connect..`); | 8541 | const quiet = isTrueBoolean(args?.quiet); |
| 8542 | const toast = quiet ? jQuery() : toastr.info(`API set to ${text}, trying to connect..`); | ||
| 8516 | 8543 | ||
| 8517 | try { | 8544 | try { |
| 8518 | await waitUntilCondition(() => online_status !== 'no_connection', 10000, 100); | 8545 | await waitUntilCondition(() => online_status !== 'no_connection', 10000, 100); |
| 8519 | console.log('Connection successful'); | 8546 | console.log('Connection successful'); |
| 8520 | } catch { | 8547 | } catch { |
| 8521 | console.log('Could not connect after 5 seconds, skipping.'); | 8548 | console.log('Could not connect after 10 seconds, skipping.'); |
| 8522 | } | 8549 | } |
| 8550 | |||
| 8551 | toastr.clear(toast); | ||
| 8552 | return text; | ||
| 8523 | } | 8553 | } |
| 8524 | 8554 | ||
| 8525 | /** | 8555 | /** |
| @@ -8814,16 +8844,21 @@ export async function handleDeleteCharacter(this_chid, delete_chats) { | |||
| 8814 | /** | 8844 | /** |
| 8815 | * Deletes a character completely, including associated chats if specified | 8845 | * Deletes a character completely, including associated chats if specified |
| 8816 | * | 8846 | * |
| 8817 | * @param {string} characterKey - The key (avatar) of the character to be deleted | 8847 | * @param {string|string[]} characterKey - The key (avatar) of the character to be deleted |
| 8818 | * @param {Object} [options] - Optional parameters for the deletion | 8848 | * @param {Object} [options] - Optional parameters for the deletion |
| 8819 | * @param {boolean} [options.deleteChats=true] - Whether to delete associated chats or not | 8849 | * @param {boolean} [options.deleteChats=true] - Whether to delete associated chats or not |
| 8820 | * @return {Promise<void>} - A promise that resolves when the character is successfully deleted | 8850 | * @return {Promise<void>} - A promise that resolves when the character is successfully deleted |
| 8821 | */ | 8851 | */ |
| 8822 | export async function deleteCharacter(characterKey, { deleteChats = true } = {}) { | 8852 | export async function deleteCharacter(characterKey, { deleteChats = true } = {}) { |
| 8823 | const character = characters.find(x => x.avatar == characterKey); | 8853 | if (!Array.isArray(characterKey)) { |
| 8854 | characterKey = [characterKey]; | ||
| 8855 | } | ||
| 8856 | |||
| 8857 | for (const key of characterKey) { | ||
| 8858 | const character = characters.find(x => x.avatar == key); | ||
| 8824 | if (!character) { | 8859 | if (!character) { |
| 8825 | toastr.warning(`Character ${characterKey} not found. Cannot be deleted.`); | 8860 | toastr.warning(`Character ${key} not found. Skipping deletion.`); |
| 8826 | return; | 8861 | continue; |
| 8827 | } | 8862 | } |
| 8828 | 8863 | ||
| 8829 | const chid = characters.indexOf(character); | 8864 | const chid = characters.indexOf(character); |
| @@ -8839,10 +8874,12 @@ export async function deleteCharacter(characterKey, { deleteChats = true } = {}) | |||
| 8839 | }); | 8874 | }); |
| 8840 | 8875 | ||
| 8841 | if (!response.ok) { | 8876 | if (!response.ok) { |
| 8842 | throw new Error(`Failed to delete character: ${response.status} ${response.statusText}`); | 8877 | toastr.error(`${response.status} ${response.statusText}`, 'Failed to delete character'); |
| 8878 | continue; | ||
| 8843 | } | 8879 | } |
| 8844 | 8880 | ||
| 8845 | await removeCharacterFromUI(character.name, character.avatar); | 8881 | delete tag_map[character.avatar]; |
| 8882 | select_rm_info('char_delete', character.name); | ||
| 8846 | 8883 | ||
| 8847 | if (deleteChats) { | 8884 | if (deleteChats) { |
| 8848 | for (const chat of pastChats) { | 8885 | for (const chat of pastChats) { |
| @@ -8851,35 +8888,30 @@ export async function deleteCharacter(characterKey, { deleteChats = true } = {}) | |||
| 8851 | } | 8888 | } |
| 8852 | } | 8889 | } |
| 8853 | 8890 | ||
| 8854 | eventSource.emit(event_types.CHARACTER_DELETED, { id: this_chid, character: characters[this_chid] }); | 8891 | await eventSource.emit(event_types.CHARACTER_DELETED, { id: chid, character: character }); |
| 8892 | } | ||
| 8893 | |||
| 8894 | await removeCharacterFromUI(); | ||
| 8855 | } | 8895 | } |
| 8856 | 8896 | ||
| 8857 | /** | 8897 | /** |
| 8858 | * Function to delete a character from UI after character deletion API success. | 8898 | * Function to delete a character from UI after character deletion API success. |
| 8859 | * It manages necessary UI changes such as closing advanced editing popup, unsetting | 8899 | * It manages necessary UI changes such as closing advanced editing popup, unsetting |
| 8860 | * character ID, resetting characters array and chat metadata, deselecting character's tab | 8900 | * character ID, resetting characters array and chat metadata, deselecting character's tab |
| 8861 | * panel, removing character name from navigation tabs, clearing chat, removing character's | 8901 | * panel, removing character name from navigation tabs, clearing chat, fetching updated list of characters. |
| 8862 | * avatar from tag_map, fetching updated list of characters and updating the 'deleted | ||
| 8863 | * character' message. | ||
| 8864 | * It also ensures to save the settings after all the operations. | 8902 | * It also ensures to save the settings after all the operations. |
| 8865 | * | ||
| 8866 | * @param {string} name - The name of the character to be deleted. | ||
| 8867 | * @param {string} avatar - The avatar URL of the character to be deleted. | ||
| 8868 | * @param {boolean} reloadCharacters - Whether the character list should be refreshed after deletion. | ||
| 8869 | */ | 8903 | */ |
| 8870 | async function removeCharacterFromUI(name, avatar, reloadCharacters = true) { | 8904 | async function removeCharacterFromUI() { |
| 8871 | await clearChat(); | 8905 | await clearChat(); |
| 8872 | $('#character_cross').click(); | 8906 | $('#character_cross').click(); |
| 8873 | this_chid = undefined; | 8907 | this_chid = undefined; |
| 8874 | characters.length = 0; | 8908 | characters.length = 0; |
| 8875 | name2 = systemUserName; | 8909 | name2 = systemUserName; |
| 8876 | chat = [...safetychat]; | 8910 | chat.splice(0, chat.length, ...SAFETY_CHAT); |
| 8877 | chat_metadata = {}; | 8911 | chat_metadata = {}; |
| 8878 | $(document.getElementById('rm_button_selected_ch')).children('h2').text(''); | 8912 | $(document.getElementById('rm_button_selected_ch')).children('h2').text(''); |
| 8879 | this_chid = undefined; | 8913 | this_chid = undefined; |
| 8880 | delete tag_map[avatar]; | 8914 | await getCharacters(); |
| 8881 | if (reloadCharacters) await getCharacters(); | ||
| 8882 | select_rm_info('char_delete', name); | ||
| 8883 | await printMessages(); | 8915 | await printMessages(); |
| 8884 | saveSettingsDebounced(); | 8916 | saveSettingsDebounced(); |
| 8885 | } | 8917 | } |
| @@ -8978,6 +9010,15 @@ jQuery(async function () { | |||
| 8978 | name: 'api', | 9010 | name: 'api', |
| 8979 | callback: connectAPISlash, | 9011 | callback: connectAPISlash, |
| 8980 | returns: 'the current API', | 9012 | returns: 'the current API', |
| 9013 | namedArgumentList: [ | ||
| 9014 | SlashCommandNamedArgument.fromProps({ | ||
| 9015 | name: 'quiet', | ||
| 9016 | description: 'Suppress the toast message on connection', | ||
| 9017 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 9018 | defaultValue: 'false', | ||
| 9019 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 9020 | }), | ||
| 9021 | ], | ||
| 8981 | unnamedArgumentList: [ | 9022 | unnamedArgumentList: [ |
| 8982 | SlashCommandArgument.fromProps({ | 9023 | SlashCommandArgument.fromProps({ |
| 8983 | description: 'API to connect to', | 9024 | description: 'API to connect to', |
| @@ -9497,11 +9538,7 @@ jQuery(async function () { | |||
| 9497 | const oldFileNameFull = $(this).closest('.select_chat_block_wrapper').find('.select_chat_block_filename').text(); | 9538 | const oldFileNameFull = $(this).closest('.select_chat_block_wrapper').find('.select_chat_block_filename').text(); |
| 9498 | const oldFileName = oldFileNameFull.replace('.jsonl', ''); | 9539 | const oldFileName = oldFileNameFull.replace('.jsonl', ''); |
| 9499 | 9540 | ||
| 9500 | const popupText = `<h3>Enter the new name for the chat:<h3> | 9541 | const popupText = await renderTemplateAsync('chatRename'); |
| 9501 | <small>!!Using an existing filename will produce an error!!<br> | ||
| 9502 | This will break the link between checkpoint chats.<br> | ||
| 9503 | No need to add '.jsonl' at the end.<br> | ||
| 9504 | </small>`; | ||
| 9505 | const newName = await callPopup(popupText, 'input', oldFileName); | 9542 | const newName = await callPopup(popupText, 'input', oldFileName); |
| 9506 | 9543 | ||
| 9507 | if (!newName || newName == oldFileName) { | 9544 | if (!newName || newName == oldFileName) { |
| @@ -9709,12 +9746,7 @@ jQuery(async function () { | |||
| 9709 | else if (id == 'option_start_new_chat') { | 9746 | else if (id == 'option_start_new_chat') { |
| 9710 | if ((selected_group || this_chid !== undefined) && !is_send_press) { | 9747 | if ((selected_group || this_chid !== undefined) && !is_send_press) { |
| 9711 | let deleteCurrentChat = false; | 9748 | let deleteCurrentChat = false; |
| 9712 | const result = await Popup.show.confirm('Start new chat?', ` | 9749 | const result = await Popup.show.confirm(t`Start new chat?`, await renderTemplateAsync('newChatConfirm'), { |
| 9713 | <label for="del_chat_checkbox" class="checkbox_label justifyCenter" | ||
| 9714 | title="If necessary, you can later restore this chat file from the /backups folder"> | ||
| 9715 | <input type="checkbox" id="del_chat_checkbox" /> | ||
| 9716 | <small>Also delete the current chat file</small> | ||
| 9717 | </label>`, { | ||
| 9718 | onClose: () => deleteCurrentChat = !!$('#del_chat_checkbox').prop('checked'), | 9750 | onClose: () => deleteCurrentChat = !!$('#del_chat_checkbox').prop('checked'), |
| 9719 | }); | 9751 | }); |
| 9720 | if (!result) { | 9752 | if (!result) { |
| @@ -10226,10 +10258,10 @@ jQuery(async function () { | |||
| 10226 | 10258 | ||
| 10227 | let deleteOnlySwipe = false; | 10259 | let deleteOnlySwipe = false; |
| 10228 | if (power_user.confirm_message_delete && fromSlashCommand !== true) { | 10260 | if (power_user.confirm_message_delete && fromSlashCommand !== true) { |
| 10229 | const result = await callGenericPopup('Are you sure you want to delete this message?', POPUP_TYPE.CONFIRM, null, { | 10261 | const result = await callGenericPopup(t`Are you sure you want to delete this message?`, POPUP_TYPE.CONFIRM, null, { |
| 10230 | okButton: canDeleteSwipe ? 'Delete Swipe' : 'Delete Message', | 10262 | okButton: canDeleteSwipe ? t`Delete Swipe` : t`Delete Message`, |
| 10231 | cancelButton: 'Cancel', | 10263 | cancelButton: 'Cancel', |
| 10232 | customButtons: canDeleteSwipe ? ['Delete Message'] : null, | 10264 | customButtons: canDeleteSwipe ? [t`Delete Message`] : null, |
| 10233 | }); | 10265 | }); |
| 10234 | if (!result) { | 10266 | if (!result) { |
| 10235 | return; | 10267 | return; |
| @@ -108,14 +108,12 @@ class CharacterContextMenu { | |||
| 108 | * Delete one or more characters, | 108 | * Delete one or more characters, |
| 109 | * opens a popup. | 109 | * opens a popup. |
| 110 | * | 110 | * |
| 111 | * @param {number} characterId | 111 | * @param {string|string[]} characterKey |
| 112 | * @param {boolean} [deleteChats] | 112 | * @param {boolean} [deleteChats] |
| 113 | * @returns {Promise<void>} | 113 | * @returns {Promise<void>} |
| 114 | */ | 114 | */ |
| 115 | static delete = async (characterId, deleteChats = false) => { | 115 | static delete = async (characterKey, deleteChats = false) => { |
| 116 | const character = CharacterContextMenu.#getCharacter(characterId); | 116 | await deleteCharacter(characterKey, { deleteChats: deleteChats }); |
| 117 | |||
| 118 | await deleteCharacter(character.avatar, { deleteChats: deleteChats }); | ||
| 119 | }; | 117 | }; |
| 120 | 118 | ||
| 121 | static #getCharacter = (characterId) => characters[characterId] ?? null; | 119 | static #getCharacter = (characterId) => characters[characterId] ?? null; |
| @@ -599,8 +597,7 @@ class BulkEditOverlay { | |||
| 599 | 597 | ||
| 600 | this.container.removeEventListener('mouseup', cancelHold); | 598 | this.container.removeEventListener('mouseup', cancelHold); |
| 601 | this.container.removeEventListener('touchend', cancelHold); | 599 | this.container.removeEventListener('touchend', cancelHold); |
| 602 | }, | 600 | }, BulkEditOverlay.longPressDelay); |
| 603 | BulkEditOverlay.longPressDelay); | ||
| 604 | }; | 601 | }; |
| 605 | 602 | ||
| 606 | handleLongPressEnd = (event) => { | 603 | handleLongPressEnd = (event) => { |
| @@ -847,11 +844,14 @@ class BulkEditOverlay { | |||
| 847 | const deleteChats = document.getElementById('del_char_checkbox').checked ?? false; | 844 | const deleteChats = document.getElementById('del_char_checkbox').checked ?? false; |
| 848 | 845 | ||
| 849 | showLoader(); | 846 | showLoader(); |
| 850 | toastr.info('We\'re deleting your characters, please wait...', 'Working on it'); | 847 | const toast = toastr.info('We\'re deleting your characters, please wait...', 'Working on it'); |
| 851 | return Promise.allSettled(characterIds.map(async characterId => CharacterContextMenu.delete(characterId, deleteChats))) | 848 | const avatarList = characterIds.map(id => characters[id]?.avatar).filter(a => a); |
| 852 | .then(() => getCharacters()) | 849 | return CharacterContextMenu.delete(avatarList, deleteChats) |
| 853 | .then(() => this.browseState()) | 850 | .then(() => this.browseState()) |
| 854 | .finally(() => hideLoader()); | 851 | .finally(() => { |
| 852 | toastr.clear(toast); | ||
| 853 | hideLoader(); | ||
| 854 | }); | ||
| 855 | }); | 855 | }); |
| 856 | 856 | ||
| 857 | // At this moment the popup is already changed in the dom, but not yet closed/resolved. We build the avatar list here | 857 | // At this moment the popup is already changed in the dom, but not yet closed/resolved. We build the avatar list here |
| @@ -21,6 +21,7 @@ const defaultUrl = 'http://localhost:5100'; | |||
| 21 | let saveMetadataTimeout = null; | 21 | let saveMetadataTimeout = null; |
| 22 | 22 | ||
| 23 | let requiresReload = false; | 23 | let requiresReload = false; |
| 24 | let stateChanged = false; | ||
| 24 | 25 | ||
| 25 | export function saveMetadataDebounced() { | 26 | export function saveMetadataDebounced() { |
| 26 | const context = getContext(); | 27 | const context = getContext(); |
| @@ -238,6 +239,7 @@ function onEnableExtensionClick() { | |||
| 238 | 239 | ||
| 239 | async function enableExtension(name, reload = true) { | 240 | async function enableExtension(name, reload = true) { |
| 240 | extension_settings.disabledExtensions = extension_settings.disabledExtensions.filter(x => x !== name); | 241 | extension_settings.disabledExtensions = extension_settings.disabledExtensions.filter(x => x !== name); |
| 242 | stateChanged = true; | ||
| 241 | await saveSettings(); | 243 | await saveSettings(); |
| 242 | if (reload) { | 244 | if (reload) { |
| 243 | location.reload(); | 245 | location.reload(); |
| @@ -248,6 +250,7 @@ async function enableExtension(name, reload = true) { | |||
| 248 | 250 | ||
| 249 | async function disableExtension(name, reload = true) { | 251 | async function disableExtension(name, reload = true) { |
| 250 | extension_settings.disabledExtensions.push(name); | 252 | extension_settings.disabledExtensions.push(name); |
| 253 | stateChanged = true; | ||
| 251 | await saveSettings(); | 254 | await saveSettings(); |
| 252 | if (reload) { | 255 | if (reload) { |
| 253 | location.reload(); | 256 | location.reload(); |
| @@ -304,7 +307,7 @@ async function activateExtensions() { | |||
| 304 | 307 | ||
| 305 | if (!isDisabled) { | 308 | if (!isDisabled) { |
| 306 | const promise = Promise.all([addExtensionScript(name, manifest), addExtensionStyle(name, manifest)]); | 309 | const promise = Promise.all([addExtensionScript(name, manifest), addExtensionStyle(name, manifest)]); |
| 307 | promise | 310 | await promise |
| 308 | .then(() => activeExtensions.add(name)) | 311 | .then(() => activeExtensions.add(name)) |
| 309 | .catch(err => console.log('Could not activate extension: ' + name, err)); | 312 | .catch(err => console.log('Could not activate extension: ' + name, err)); |
| 310 | promises.push(promise); | 313 | promises.push(promise); |
| @@ -657,7 +660,29 @@ async function showExtensionsDetails() { | |||
| 657 | await oldPopup.complete(POPUP_RESULT.CANCELLED); | 660 | await oldPopup.complete(POPUP_RESULT.CANCELLED); |
| 658 | } | 661 | } |
| 659 | 662 | ||
| 660 | const popup = new Popup(html, POPUP_TYPE.TEXT, '', { okButton: 'Close', wide: true, large: true, customButtons: [updateAllButton], allowVerticalScrolling: true }); | 663 | let waitingForSave = false; |
| 664 | |||
| 665 | const popup = new Popup(html, POPUP_TYPE.TEXT, '', { | ||
| 666 | okButton: 'Close', | ||
| 667 | wide: true, | ||
| 668 | large: true, | ||
| 669 | customButtons: [updateAllButton], | ||
| 670 | allowVerticalScrolling: true, | ||
| 671 | onClosing: async () => { | ||
| 672 | if (waitingForSave) { | ||
| 673 | return false; | ||
| 674 | } | ||
| 675 | if (stateChanged) { | ||
| 676 | waitingForSave = true; | ||
| 677 | const toast = toastr.info('The page will be reloaded shortly...', 'Extensions state changed'); | ||
| 678 | await saveSettings(); | ||
| 679 | toastr.clear(toast); | ||
| 680 | waitingForSave = false; | ||
| 681 | requiresReload = true; | ||
| 682 | } | ||
| 683 | return true; | ||
| 684 | }, | ||
| 685 | }); | ||
| 661 | popupPromise = popup.show(); | 686 | popupPromise = popup.show(); |
| 662 | } catch (error) { | 687 | } catch (error) { |
| 663 | toastr.error('Error loading extensions. See browser console for details.'); | 688 | toastr.error('Error loading extensions. See browser console for details.'); |
| @@ -797,16 +822,17 @@ export async function installExtension(url) { | |||
| 797 | const response = await request.json(); | 822 | const response = await request.json(); |
| 798 | toastr.success(`Extension "${response.display_name}" by ${response.author} (version ${response.version}) has been installed successfully!`, 'Extension installation successful'); | 823 | toastr.success(`Extension "${response.display_name}" by ${response.author} (version ${response.version}) has been installed successfully!`, 'Extension installation successful'); |
| 799 | console.debug(`Extension "${response.display_name}" has been installed successfully at ${response.extensionPath}`); | 824 | console.debug(`Extension "${response.display_name}" has been installed successfully at ${response.extensionPath}`); |
| 800 | await loadExtensionSettings({}, false); | 825 | await loadExtensionSettings({}, false, false); |
| 801 | eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED); | 826 | await eventSource.emit(event_types.EXTENSION_SETTINGS_LOADED); |
| 802 | } | 827 | } |
| 803 | 828 | ||
| 804 | /** | 829 | /** |
| 805 | * Loads extension settings from the app settings. | 830 | * Loads extension settings from the app settings. |
| 806 | * @param {object} settings App Settings | 831 | * @param {object} settings App Settings |
| 807 | * @param {boolean} versionChanged Is this a version change? | 832 | * @param {boolean} versionChanged Is this a version change? |
| 833 | * @param {boolean} enableAutoUpdate Enable auto-update | ||
| 808 | */ | 834 | */ |
| 809 | async function loadExtensionSettings(settings, versionChanged) { | 835 | async function loadExtensionSettings(settings, versionChanged, enableAutoUpdate) { |
| 810 | if (settings.extension_settings) { | 836 | if (settings.extension_settings) { |
| 811 | Object.assign(extension_settings, settings.extension_settings); | 837 | Object.assign(extension_settings, settings.extension_settings); |
| 812 | } | 838 | } |
| @@ -817,11 +843,11 @@ async function loadExtensionSettings(settings, versionChanged) { | |||
| 817 | $('#extensions_notify_updates').prop('checked', extension_settings.notifyUpdates); | 843 | $('#extensions_notify_updates').prop('checked', extension_settings.notifyUpdates); |
| 818 | 844 | ||
| 819 | // Activate offline extensions | 845 | // Activate offline extensions |
| 820 | eventSource.emit(event_types.EXTENSIONS_FIRST_LOAD); | 846 | await eventSource.emit(event_types.EXTENSIONS_FIRST_LOAD); |
| 821 | extensionNames = await discoverExtensions(); | 847 | extensionNames = await discoverExtensions(); |
| 822 | manifests = await getManifests(extensionNames); | 848 | manifests = await getManifests(extensionNames); |
| 823 | 849 | ||
| 824 | if (versionChanged) { | 850 | if (versionChanged && enableAutoUpdate) { |
| 825 | await autoUpdateExtensions(false); | 851 | await autoUpdateExtensions(false); |
| 826 | } | 852 | } |
| 827 | 853 | ||
| @@ -20,7 +20,7 @@ | |||
| 20 | <option value="zerooneai">01.AI (Yi)</option> | 20 | <option value="zerooneai">01.AI (Yi)</option> |
| 21 | <option value="anthropic">Anthropic</option> | 21 | <option value="anthropic">Anthropic</option> |
| 22 | <option value="custom" data-i18n="Custom (OpenAI-compatible)">Custom (OpenAI-compatible)</option> | 22 | <option value="custom" data-i18n="Custom (OpenAI-compatible)">Custom (OpenAI-compatible)</option> |
| 23 | <option value="google">Google MakerSuite</option> | 23 | <option value="google">Google AI Studio</option> |
| 24 | <option value="koboldcpp">KoboldCpp</option> | 24 | <option value="koboldcpp">KoboldCpp</option> |
| 25 | <option value="llamacpp">llama.cpp</option> | 25 | <option value="llamacpp">llama.cpp</option> |
| 26 | <option value="ollama">Ollama</option> | 26 | <option value="ollama">Ollama</option> |
| @@ -45,8 +45,11 @@ | |||
| 45 | <option data-type="anthropic" value="claude-3-haiku-20240307">claude-3-haiku-20240307</option> | 45 | <option data-type="anthropic" value="claude-3-haiku-20240307">claude-3-haiku-20240307</option> |
| 46 | <option data-type="google" value="gemini-pro-vision">gemini-pro-vision</option> | 46 | <option data-type="google" value="gemini-pro-vision">gemini-pro-vision</option> |
| 47 | <option data-type="google" value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option> | 47 | <option data-type="google" value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option> |
| 48 | <option data-type="google" value="gemini-1.5-flash-exp-0827">gemini-1.5-flash-exp-0827</option> | ||
| 49 | <option data-type="google" value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option> | ||
| 48 | <option data-type="google" value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option> | 50 | <option data-type="google" value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option> |
| 49 | <option data-type="google" value="gemini-1.5-pro-exp-0801">gemini-1.5-pro-exp-0801</option> | 51 | <option data-type="google" value="gemini-1.5-pro-exp-0801">gemini-1.5-pro-exp-0801</option> |
| 52 | <option data-type="google" value="gemini-1.5-pro-exp-0827">gemini-1.5-pro-exp-0827</option> | ||
| 50 | <option data-type="openrouter" value="openai/gpt-4-vision-preview">openai/gpt-4-vision-preview</option> | 53 | <option data-type="openrouter" value="openai/gpt-4-vision-preview">openai/gpt-4-vision-preview</option> |
| 51 | <option data-type="openrouter" value="openai/gpt-4o">openai/gpt-4o</option> | 54 | <option data-type="openrouter" value="openai/gpt-4o">openai/gpt-4o</option> |
| 52 | <option data-type="openrouter" value="openai/gpt-4-turbo">openai/gpt-4-turbo</option> | 55 | <option data-type="openrouter" value="openai/gpt-4-turbo">openai/gpt-4-turbo</option> |
| @@ -1,4 +1,4 @@ | |||
| 1 | import { getStringHash, debounce, waitUntilCondition, extractAllWords } from '../../utils.js'; | 1 | import { getStringHash, debounce, waitUntilCondition, extractAllWords, isTrueBoolean } from '../../utils.js'; |
| 2 | import { getContext, getApiUrl, extension_settings, doExtrasFetch, modules, renderExtensionTemplateAsync } from '../../extensions.js'; | 2 | import { getContext, getApiUrl, extension_settings, doExtrasFetch, modules, renderExtensionTemplateAsync } from '../../extensions.js'; |
| 3 | import { | 3 | import { |
| 4 | activateSendButtons, | 4 | activateSendButtons, |
| @@ -26,6 +26,7 @@ import { SlashCommand } from '../../slash-commands/SlashCommand.js'; | |||
| 26 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js'; | 26 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js'; |
| 27 | import { MacrosParser } from '../../macros.js'; | 27 | import { MacrosParser } from '../../macros.js'; |
| 28 | import { countWebLlmTokens, generateWebLlmChatPrompt, getWebLlmContextSize, isWebLlmSupported } from '../shared.js'; | 28 | import { countWebLlmTokens, generateWebLlmChatPrompt, getWebLlmContextSize, isWebLlmSupported } from '../shared.js'; |
| 29 | import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; | ||
| 29 | export { MODULE_NAME }; | 30 | export { MODULE_NAME }; |
| 30 | 31 | ||
| 31 | const MODULE_NAME = '1_memory'; | 32 | const MODULE_NAME = '1_memory'; |
| @@ -456,7 +457,12 @@ async function onChatEvent() { | |||
| 456 | } | 457 | } |
| 457 | } | 458 | } |
| 458 | 459 | ||
| 459 | async function forceSummarizeChat() { | 460 | /** |
| 461 | * Forces a summary generation for the current chat. | ||
| 462 | * @param {boolean} quiet If an informational toast should be displayed | ||
| 463 | * @returns {Promise<string>} Summarized text | ||
| 464 | */ | ||
| 465 | async function forceSummarizeChat(quiet) { | ||
| 460 | if (extension_settings.memory.source === summary_sources.extras) { | 466 | if (extension_settings.memory.source === summary_sources.extras) { |
| 461 | toastr.warning('Force summarization is not supported for Extras API'); | 467 | toastr.warning('Force summarization is not supported for Extras API'); |
| 462 | return; | 468 | return; |
| @@ -471,7 +477,7 @@ async function forceSummarizeChat() { | |||
| 471 | return ''; | 477 | return ''; |
| 472 | } | 478 | } |
| 473 | 479 | ||
| 474 | const toast = toastr.info('Summarizing chat...', 'Please wait', { timeOut: 0, extendedTimeOut: 0 }); | 480 | const toast = quiet ? jQuery() : toastr.info('Summarizing chat...', 'Please wait', { timeOut: 0, extendedTimeOut: 0 }); |
| 475 | const value = extension_settings.memory.source === summary_sources.main | 481 | const value = extension_settings.memory.source === summary_sources.main |
| 476 | ? await summarizeChatMain(context, true, skipWIAN) | 482 | ? await summarizeChatMain(context, true, skipWIAN) |
| 477 | : await summarizeChatWebLLM(context, true); | 483 | : await summarizeChatWebLLM(context, true); |
| @@ -494,9 +500,10 @@ async function forceSummarizeChat() { | |||
| 494 | async function summarizeCallback(args, text) { | 500 | async function summarizeCallback(args, text) { |
| 495 | text = text.trim(); | 501 | text = text.trim(); |
| 496 | 502 | ||
| 497 | // Using forceSummarizeChat to summarize the current chat | 503 | // Summarize the current chat if no text provided |
| 498 | if (!text) { | 504 | if (!text) { |
| 499 | return await forceSummarizeChat(); | 505 | const quiet = isTrueBoolean(args.quiet); |
| 506 | return await forceSummarizeChat(quiet); | ||
| 500 | } | 507 | } |
| 501 | 508 | ||
| 502 | const source = args.source || extension_settings.memory.source; | 509 | const source = args.source || extension_settings.memory.source; |
| @@ -1005,7 +1012,7 @@ function setupListeners() { | |||
| 1005 | $('#memory_prompt_words').off('click').on('input', onMemoryPromptWordsInput); | 1012 | $('#memory_prompt_words').off('click').on('input', onMemoryPromptWordsInput); |
| 1006 | $('#memory_prompt_interval').off('click').on('input', onMemoryPromptIntervalInput); | 1013 | $('#memory_prompt_interval').off('click').on('input', onMemoryPromptIntervalInput); |
| 1007 | $('#memory_prompt').off('click').on('input', onMemoryPromptInput); | 1014 | $('#memory_prompt').off('click').on('input', onMemoryPromptInput); |
| 1008 | $('#memory_force_summarize').off('click').on('click', forceSummarizeChat); | 1015 | $('#memory_force_summarize').off('click').on('click', () => forceSummarizeChat(false)); |
| 1009 | $('#memory_template').off('click').on('input', onMemoryTemplateInput); | 1016 | $('#memory_template').off('click').on('input', onMemoryTemplateInput); |
| 1010 | $('#memory_depth').off('click').on('input', onMemoryDepthInput); | 1017 | $('#memory_depth').off('click').on('input', onMemoryDepthInput); |
| 1011 | $('#memory_role').off('click').on('input', onMemoryRoleInput); | 1018 | $('#memory_role').off('click').on('input', onMemoryRoleInput); |
| @@ -1055,6 +1062,13 @@ jQuery(async function () { | |||
| 1055 | typeList: [ARGUMENT_TYPE.STRING], | 1062 | typeList: [ARGUMENT_TYPE.STRING], |
| 1056 | defaultValue: '', | 1063 | defaultValue: '', |
| 1057 | }), | 1064 | }), |
| 1065 | SlashCommandNamedArgument.fromProps({ | ||
| 1066 | name: 'quiet', | ||
| 1067 | description: 'suppress the toast message when summarizing the chat', | ||
| 1068 | typeList: [ARGUMENT_TYPE.BOOLEAN], | ||
| 1069 | defaultValue: 'false', | ||
| 1070 | enumList: commonEnumProviders.boolean('trueFalse')(), | ||
| 1071 | }), | ||
| 1058 | ], | 1072 | ], |
| 1059 | unnamedArgumentList: [ | 1073 | unnamedArgumentList: [ |
| 1060 | new SlashCommandArgument('text to summarize', [ARGUMENT_TYPE.STRING], false, false, ''), | 1074 | new SlashCommandArgument('text to summarize', [ARGUMENT_TYPE.STRING], false, false, ''), |
| @@ -11,6 +11,9 @@ | |||
| 11 | <label class="flex-container"> | 11 | <label class="flex-container"> |
| 12 | <input type="checkbox" id="qr--isCombined"><span data-i18n="Combine Quick Replies">Combine Quick Replies</span> | 12 | <input type="checkbox" id="qr--isCombined"><span data-i18n="Combine Quick Replies">Combine Quick Replies</span> |
| 13 | </label> | 13 | </label> |
| 14 | <label class="flex-container"> | ||
| 15 | <input type="checkbox" id="qr--showPopoutButton"><span data-i18n="Show Popout Button">Show Popout Button</span> | ||
| 16 | </label> | ||
| 14 | 17 | ||
| 15 | <hr> | 18 | <hr> |
| 16 | 19 | ||
| @@ -16,6 +16,7 @@ export class QuickReplySettings { | |||
| 16 | /**@type {Boolean}*/ isEnabled = false; | 16 | /**@type {Boolean}*/ isEnabled = false; |
| 17 | /**@type {Boolean}*/ isCombined = false; | 17 | /**@type {Boolean}*/ isCombined = false; |
| 18 | /**@type {Boolean}*/ isPopout = false; | 18 | /**@type {Boolean}*/ isPopout = false; |
| 19 | /**@type {Boolean}*/ showPopoutButton = true; | ||
| 19 | /**@type {QuickReplyConfig}*/ config; | 20 | /**@type {QuickReplyConfig}*/ config; |
| 20 | /**@type {QuickReplyConfig}*/ _chatConfig; | 21 | /**@type {QuickReplyConfig}*/ _chatConfig; |
| 21 | get chatConfig() { | 22 | get chatConfig() { |
| @@ -79,6 +80,7 @@ export class QuickReplySettings { | |||
| 79 | isEnabled: this.isEnabled, | 80 | isEnabled: this.isEnabled, |
| 80 | isCombined: this.isCombined, | 81 | isCombined: this.isCombined, |
| 81 | isPopout: this.isPopout, | 82 | isPopout: this.isPopout, |
| 83 | showPopoutButton: this.showPopoutButton, | ||
| 82 | config: this.config, | 84 | config: this.config, |
| 83 | }; | 85 | }; |
| 84 | } | 86 | } |
| @@ -69,6 +69,8 @@ export class ButtonUi { | |||
| 69 | root.id = 'qr--bar'; | 69 | root.id = 'qr--bar'; |
| 70 | root.classList.add('flex-container'); | 70 | root.classList.add('flex-container'); |
| 71 | root.classList.add('flexGap5'); | 71 | root.classList.add('flexGap5'); |
| 72 | if (this.settings.showPopoutButton) { | ||
| 73 | root.classList.add('popoutVisible'); | ||
| 72 | const popout = document.createElement('div'); { | 74 | const popout = document.createElement('div'); { |
| 73 | popout.id = 'qr--popoutTrigger'; | 75 | popout.id = 'qr--popoutTrigger'; |
| 74 | popout.classList.add('menu_button'); | 76 | popout.classList.add('menu_button'); |
| @@ -81,6 +83,7 @@ export class ButtonUi { | |||
| 81 | }); | 83 | }); |
| 82 | root.append(popout); | 84 | root.append(popout); |
| 83 | } | 85 | } |
| 86 | } | ||
| 84 | if (this.settings.isCombined) { | 87 | if (this.settings.isCombined) { |
| 85 | const buttons = document.createElement('div'); { | 88 | const buttons = document.createElement('div'); { |
| 86 | buttonHolder = buttons; | 89 | buttonHolder = buttons; |
| @@ -14,6 +14,7 @@ export class SettingsUi { | |||
| 14 | 14 | ||
| 15 | /**@type {HTMLInputElement}*/ isEnabled; | 15 | /**@type {HTMLInputElement}*/ isEnabled; |
| 16 | /**@type {HTMLInputElement}*/ isCombined; | 16 | /**@type {HTMLInputElement}*/ isCombined; |
| 17 | /**@type {HTMLInputElement}*/ showPopoutButton; | ||
| 17 | 18 | ||
| 18 | /**@type {HTMLElement}*/ globalSetList; | 19 | /**@type {HTMLElement}*/ globalSetList; |
| 19 | 20 | ||
| @@ -79,6 +80,10 @@ export class SettingsUi { | |||
| 79 | this.isCombined = this.dom.querySelector('#qr--isCombined'); | 80 | this.isCombined = this.dom.querySelector('#qr--isCombined'); |
| 80 | this.isCombined.checked = this.settings.isCombined; | 81 | this.isCombined.checked = this.settings.isCombined; |
| 81 | this.isCombined.addEventListener('click', ()=>this.onIsCombined()); | 82 | this.isCombined.addEventListener('click', ()=>this.onIsCombined()); |
| 83 | |||
| 84 | this.showPopoutButton = this.dom.querySelector('#qr--showPopoutButton'); | ||
| 85 | this.showPopoutButton.checked = this.settings.showPopoutButton; | ||
| 86 | this.showPopoutButton.addEventListener('click', ()=>this.onShowPopoutButton()); | ||
| 82 | } | 87 | } |
| 83 | 88 | ||
| 84 | prepareGlobalSetList() { | 89 | prepareGlobalSetList() { |
| @@ -235,6 +240,11 @@ export class SettingsUi { | |||
| 235 | this.settings.save(); | 240 | this.settings.save(); |
| 236 | } | 241 | } |
| 237 | 242 | ||
| 243 | async onShowPopoutButton() { | ||
| 244 | this.settings.showPopoutButton = this.showPopoutButton.checked; | ||
| 245 | this.settings.save(); | ||
| 246 | } | ||
| 247 | |||
| 238 | async onGlobalSetListSort() { | 248 | async onGlobalSetListSort() { |
| 239 | this.settings.config.setList = Array.from(this.globalSetList.children).map((it,idx)=>{ | 249 | this.settings.config.setList = Array.from(this.globalSetList.children).map((it,idx)=>{ |
| 240 | const set = this.settings.config.setList[Number(it.getAttribute('data-order'))]; | 250 | const set = this.settings.config.setList[Number(it.getAttribute('data-order'))]; |
| @@ -27,7 +27,6 @@ | |||
| 27 | max-width: 100%; | 27 | max-width: 100%; |
| 28 | overflow-x: auto; | 28 | overflow-x: auto; |
| 29 | order: 1; | 29 | order: 1; |
| 30 | padding-right: 2.5em; | ||
| 31 | position: relative; | 30 | position: relative; |
| 32 | } | 31 | } |
| 33 | #qr--bar > #qr--popoutTrigger { | 32 | #qr--bar > #qr--popoutTrigger { |
| @@ -35,6 +34,9 @@ | |||
| 35 | right: 0.25em; | 34 | right: 0.25em; |
| 36 | top: 0; | 35 | top: 0; |
| 37 | } | 36 | } |
| 37 | #qr--bar.popoutVisible { | ||
| 38 | padding-right: 2.5em; | ||
| 39 | } | ||
| 38 | #qr--popout { | 40 | #qr--popout { |
| 39 | display: flex; | 41 | display: flex; |
| 40 | flex-direction: column; | 42 | flex-direction: column; |
| @@ -25,7 +25,6 @@ | |||
| 25 | max-width: 100%; | 25 | max-width: 100%; |
| 26 | overflow-x: auto; | 26 | overflow-x: auto; |
| 27 | order: 1; | 27 | order: 1; |
| 28 | padding-right: 2.5em; | ||
| 29 | position: relative; | 28 | position: relative; |
| 30 | 29 | ||
| 31 | >#qr--popoutTrigger { | 30 | >#qr--popoutTrigger { |
| @@ -34,6 +33,9 @@ | |||
| 34 | top: 0; | 33 | top: 0; |
| 35 | } | 34 | } |
| 36 | } | 35 | } |
| 36 | #qr--bar.popoutVisible { | ||
| 37 | padding-right: 2.5em; | ||
| 38 | } | ||
| 37 | 39 | ||
| 38 | #qr--popout { | 40 | #qr--popout { |
| 39 | display: flex; | 41 | display: flex; |
| @@ -141,7 +141,7 @@ function throwIfInvalidModel(useReverseProxy) { | |||
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | if (extension_settings.caption.multimodal_api === 'google' && !secret_state[SECRET_KEYS.MAKERSUITE] && !useReverseProxy) { | 143 | if (extension_settings.caption.multimodal_api === 'google' && !secret_state[SECRET_KEYS.MAKERSUITE] && !useReverseProxy) { |
| 144 | throw new Error('MakerSuite API key is not set.'); | 144 | throw new Error('Google AI Studio API key is not set.'); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | if (extension_settings.caption.multimodal_api === 'ollama' && !textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]) { | 147 | if (extension_settings.caption.multimodal_api === 'ollama' && !textgenerationwebui_settings.server_urls[textgen_types.OLLAMA]) { |
| @@ -52,6 +52,7 @@ const sources = { | |||
| 52 | pollinations: 'pollinations', | 52 | pollinations: 'pollinations', |
| 53 | stability: 'stability', | 53 | stability: 'stability', |
| 54 | blockentropy: 'blockentropy', | 54 | blockentropy: 'blockentropy', |
| 55 | huggingface: 'huggingface', | ||
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| 57 | const initiators = { | 58 | const initiators = { |
| @@ -454,6 +455,7 @@ async function loadSettings() { | |||
| 454 | $('#sd_command_visible').prop('checked', extension_settings.sd.command_visible); | 455 | $('#sd_command_visible').prop('checked', extension_settings.sd.command_visible); |
| 455 | $('#sd_interactive_visible').prop('checked', extension_settings.sd.interactive_visible); | 456 | $('#sd_interactive_visible').prop('checked', extension_settings.sd.interactive_visible); |
| 456 | $('#sd_stability_style_preset').val(extension_settings.sd.stability_style_preset); | 457 | $('#sd_stability_style_preset').val(extension_settings.sd.stability_style_preset); |
| 458 | $('#sd_huggingface_model_id').val(extension_settings.sd.huggingface_model_id); | ||
| 457 | 459 | ||
| 458 | for (const style of extension_settings.sd.styles) { | 460 | for (const style of extension_settings.sd.styles) { |
| 459 | const option = document.createElement('option'); | 461 | const option = document.createElement('option'); |
| @@ -1091,6 +1093,11 @@ function onComfyUrlInput() { | |||
| 1091 | saveSettingsDebounced(); | 1093 | saveSettingsDebounced(); |
| 1092 | } | 1094 | } |
| 1093 | 1095 | ||
| 1096 | function onHFModelInput() { | ||
| 1097 | extension_settings.sd.huggingface_model_id = $('#sd_huggingface_model_id').val(); | ||
| 1098 | saveSettingsDebounced(); | ||
| 1099 | } | ||
| 1100 | |||
| 1094 | function onComfyWorkflowChange() { | 1101 | function onComfyWorkflowChange() { |
| 1095 | extension_settings.sd.comfy_workflow = $('#sd_comfy_workflow').find(':selected').val(); | 1102 | extension_settings.sd.comfy_workflow = $('#sd_comfy_workflow').find(':selected').val(); |
| 1096 | saveSettingsDebounced(); | 1103 | saveSettingsDebounced(); |
| @@ -1235,7 +1242,16 @@ async function onModelChange() { | |||
| 1235 | extension_settings.sd.model = $('#sd_model').find(':selected').val(); | 1242 | extension_settings.sd.model = $('#sd_model').find(':selected').val(); |
| 1236 | saveSettingsDebounced(); | 1243 | saveSettingsDebounced(); |
| 1237 | 1244 | ||
| 1238 | const cloudSources = [sources.horde, sources.novel, sources.openai, sources.togetherai, sources.pollinations, sources.stability, sources.blockentropy]; | 1245 | const cloudSources = [ |
| 1246 | sources.horde, | ||
| 1247 | sources.novel, | ||
| 1248 | sources.openai, | ||
| 1249 | sources.togetherai, | ||
| 1250 | sources.pollinations, | ||
| 1251 | sources.stability, | ||
| 1252 | sources.blockentropy, | ||
| 1253 | sources.huggingface, | ||
| 1254 | ]; | ||
| 1239 | 1255 | ||
| 1240 | if (cloudSources.includes(extension_settings.sd.source)) { | 1256 | if (cloudSources.includes(extension_settings.sd.source)) { |
| 1241 | return; | 1257 | return; |
| @@ -1450,6 +1466,9 @@ async function loadSamplers() { | |||
| 1450 | case sources.blockentropy: | 1466 | case sources.blockentropy: |
| 1451 | samplers = ['N/A']; | 1467 | samplers = ['N/A']; |
| 1452 | break; | 1468 | break; |
| 1469 | case sources.huggingface: | ||
| 1470 | samplers = ['N/A']; | ||
| 1471 | break; | ||
| 1453 | } | 1472 | } |
| 1454 | 1473 | ||
| 1455 | for (const sampler of samplers) { | 1474 | for (const sampler of samplers) { |
| @@ -1639,6 +1658,9 @@ async function loadModels() { | |||
| 1639 | case sources.blockentropy: | 1658 | case sources.blockentropy: |
| 1640 | models = await loadBlockEntropyModels(); | 1659 | models = await loadBlockEntropyModels(); |
| 1641 | break; | 1660 | break; |
| 1661 | case sources.huggingface: | ||
| 1662 | models = [{ value: '', text: '<Enter Model ID above>' }]; | ||
| 1663 | break; | ||
| 1642 | } | 1664 | } |
| 1643 | 1665 | ||
| 1644 | for (const model of models) { | 1666 | for (const model of models) { |
| @@ -1986,6 +2008,9 @@ async function loadSchedulers() { | |||
| 1986 | case sources.blockentropy: | 2008 | case sources.blockentropy: |
| 1987 | schedulers = ['N/A']; | 2009 | schedulers = ['N/A']; |
| 1988 | break; | 2010 | break; |
| 2011 | case sources.huggingface: | ||
| 2012 | schedulers = ['N/A']; | ||
| 2013 | break; | ||
| 1989 | } | 2014 | } |
| 1990 | 2015 | ||
| 1991 | for (const scheduler of schedulers) { | 2016 | for (const scheduler of schedulers) { |
| @@ -2065,6 +2090,9 @@ async function loadVaes() { | |||
| 2065 | case sources.blockentropy: | 2090 | case sources.blockentropy: |
| 2066 | vaes = ['N/A']; | 2091 | vaes = ['N/A']; |
| 2067 | break; | 2092 | break; |
| 2093 | case sources.huggingface: | ||
| 2094 | vaes = ['N/A']; | ||
| 2095 | break; | ||
| 2068 | } | 2096 | } |
| 2069 | 2097 | ||
| 2070 | for (const vae of vaes) { | 2098 | for (const vae of vaes) { |
| @@ -2596,6 +2624,9 @@ async function sendGenerationRequest(generationType, prompt, additionalNegativeP | |||
| 2596 | case sources.blockentropy: | 2624 | case sources.blockentropy: |
| 2597 | result = await generateBlockEntropyImage(prefixedPrompt, negativePrompt, signal); | 2625 | result = await generateBlockEntropyImage(prefixedPrompt, negativePrompt, signal); |
| 2598 | break; | 2626 | break; |
| 2627 | case sources.huggingface: | ||
| 2628 | result = await generateHuggingFaceImage(prefixedPrompt, signal); | ||
| 2629 | break; | ||
| 2599 | } | 2630 | } |
| 2600 | 2631 | ||
| 2601 | if (!result.data) { | 2632 | if (!result.data) { |
| @@ -3229,6 +3260,34 @@ async function generateComfyImage(prompt, negativePrompt, signal) { | |||
| 3229 | return { format: 'png', data: await promptResult.text() }; | 3260 | return { format: 'png', data: await promptResult.text() }; |
| 3230 | } | 3261 | } |
| 3231 | 3262 | ||
| 3263 | |||
| 3264 | /** | ||
| 3265 | * Generates an image in Hugging Face Inference API using the provided prompt and configuration settings (model selected). | ||
| 3266 | * @param {string} prompt - The main instruction used to guide the image generation. | ||
| 3267 | * @param {AbortSignal} signal - An AbortSignal object that can be used to cancel the request. | ||
| 3268 | * @returns {Promise<{format: string, data: string}>} - A promise that resolves when the image generation and processing are complete. | ||
| 3269 | */ | ||
| 3270 | async function generateHuggingFaceImage(prompt, signal) { | ||
| 3271 | const result = await fetch('/api/sd/huggingface/generate', { | ||
| 3272 | method: 'POST', | ||
| 3273 | headers: getRequestHeaders(), | ||
| 3274 | signal: signal, | ||
| 3275 | body: JSON.stringify({ | ||
| 3276 | model: extension_settings.sd.huggingface_model_id, | ||
| 3277 | prompt: prompt, | ||
| 3278 | }), | ||
| 3279 | }); | ||
| 3280 | |||
| 3281 | if (result.ok) { | ||
| 3282 | const data = await result.json(); | ||
| 3283 | return { format: 'jpg', data: data.image }; | ||
| 3284 | } else { | ||
| 3285 | const text = await result.text(); | ||
| 3286 | throw new Error(text); | ||
| 3287 | } | ||
| 3288 | } | ||
| 3289 | |||
| 3290 | |||
| 3232 | async function onComfyOpenWorkflowEditorClick() { | 3291 | async function onComfyOpenWorkflowEditorClick() { |
| 3233 | let workflow = await (await fetch('/api/sd/comfy/workflow', { | 3292 | let workflow = await (await fetch('/api/sd/comfy/workflow', { |
| 3234 | method: 'POST', | 3293 | method: 'POST', |
| @@ -3508,6 +3567,8 @@ function isValidState() { | |||
| 3508 | return secret_state[SECRET_KEYS.STABILITY]; | 3567 | return secret_state[SECRET_KEYS.STABILITY]; |
| 3509 | case sources.blockentropy: | 3568 | case sources.blockentropy: |
| 3510 | return secret_state[SECRET_KEYS.BLOCKENTROPY]; | 3569 | return secret_state[SECRET_KEYS.BLOCKENTROPY]; |
| 3570 | case sources.huggingface: | ||
| 3571 | return secret_state[SECRET_KEYS.HUGGINGFACE]; | ||
| 3511 | } | 3572 | } |
| 3512 | } | 3573 | } |
| 3513 | 3574 | ||
| @@ -3848,6 +3909,7 @@ jQuery(async () => { | |||
| 3848 | $('#sd_swap_dimensions').on('click', onSwapDimensionsClick); | 3909 | $('#sd_swap_dimensions').on('click', onSwapDimensionsClick); |
| 3849 | $('#sd_stability_key').on('click', onStabilityKeyClick); | 3910 | $('#sd_stability_key').on('click', onStabilityKeyClick); |
| 3850 | $('#sd_stability_style_preset').on('change', onStabilityStylePresetChange); | 3911 | $('#sd_stability_style_preset').on('change', onStabilityStylePresetChange); |
| 3912 | $('#sd_huggingface_model_id').on('input', onHFModelInput); | ||
| 3851 | 3913 | ||
| 3852 | $('.sd_settings .inline-drawer-toggle').on('click', function () { | 3914 | $('.sd_settings .inline-drawer-toggle').on('click', function () { |
| 3853 | initScrollHeight($('#sd_prompt_prefix')); | 3915 | initScrollHeight($('#sd_prompt_prefix')); |
| @@ -29,7 +29,8 @@ | |||
| 29 | </label> | 29 | </label> |
| 30 | <label for="sd_expand" class="checkbox_label" data-i18n="[title]sd_expand" title="Automatically extend prompts using text generation model"> | 30 | <label for="sd_expand" class="checkbox_label" data-i18n="[title]sd_expand" title="Automatically extend prompts using text generation model"> |
| 31 | <input id="sd_expand" type="checkbox" /> | 31 | <input id="sd_expand" type="checkbox" /> |
| 32 | <span data-i18n="sd_expand_txt">Auto-enhance prompts</span> | 32 | <span data-i18n="sd_expand_txt">Auto-extend prompts</span> |
| 33 | <span class="right_menu_button fa-solid fa-triangle-exclamation" data-i18n="[title]sd_expand_warning" title="May produce unexpected results. Manual prompt editing is recommended."></span> | ||
| 33 | </label> | 34 | </label> |
| 34 | <label for="sd_snap" class="checkbox_label" data-i18n="[title]sd_snap" title="Snap generation requests with a forced aspect ratio (portraits, backgrounds) to the nearest known resolution, while trying to preserve the absolute pixel counts (recommended for SDXL)."> | 35 | <label for="sd_snap" class="checkbox_label" data-i18n="[title]sd_snap" title="Snap generation requests with a forced aspect ratio (portraits, backgrounds) to the nearest known resolution, while trying to preserve the absolute pixel counts (recommended for SDXL)."> |
| 35 | <input id="sd_snap" type="checkbox" /> | 36 | <input id="sd_snap" type="checkbox" /> |
| @@ -41,6 +42,7 @@ | |||
| 41 | <option value="comfy">ComfyUI</option> | 42 | <option value="comfy">ComfyUI</option> |
| 42 | <option value="drawthings">DrawThings HTTP API</option> | 43 | <option value="drawthings">DrawThings HTTP API</option> |
| 43 | <option value="extras">Extras API (local / remote)</option> | 44 | <option value="extras">Extras API (local / remote)</option> |
| 45 | <option value="huggingface">HuggingFace Inference API (serverless)</option> | ||
| 44 | <option value="novel">NovelAI Diffusion</option> | 46 | <option value="novel">NovelAI Diffusion</option> |
| 45 | <option value="openai">OpenAI (DALL-E)</option> | 47 | <option value="openai">OpenAI (DALL-E)</option> |
| 46 | <option value="pollinations">Pollinations</option> | 48 | <option value="pollinations">Pollinations</option> |
| @@ -82,6 +84,11 @@ | |||
| 82 | <!-- (Original Text)<b>Important:</b> run DrawThings app with HTTP API switch enabled in the UI! The server must be accessible from the SillyTavern host machine. --> | 84 | <!-- (Original Text)<b>Important:</b> run DrawThings app with HTTP API switch enabled in the UI! The server must be accessible from the SillyTavern host machine. --> |
| 83 | <i><b data-i18n="Important:">Important:</b></i><i data-i18n="sd_drawthings_auth_txt"> run DrawThings app with HTTP API switch enabled in the UI! The server must be accessible from the SillyTavern host machine.</i> | 85 | <i><b data-i18n="Important:">Important:</b></i><i data-i18n="sd_drawthings_auth_txt"> run DrawThings app with HTTP API switch enabled in the UI! The server must be accessible from the SillyTavern host machine.</i> |
| 84 | </div> | 86 | </div> |
| 87 | <div data-sd-source="huggingface"> | ||
| 88 | <i>Hint: Save an API key in the Hugging Face (Text Completion) API settings to use it here.</i> | ||
| 89 | <label for="sd_huggingface_model_id" data-i18n="Model ID">Model ID</label> | ||
| 90 | <input id="sd_huggingface_model_id" type="text" class="text_pole" data-i18n="[placeholder]e.g. black-forest-labs/FLUX.1-dev" placeholder="e.g. black-forest-labs/FLUX.1-dev" value="" /> | ||
| 91 | </div> | ||
| 85 | <div data-sd-source="vlad"> | 92 | <div data-sd-source="vlad"> |
| 86 | <label for="sd_vlad_url">SD.Next API URL</label> | 93 | <label for="sd_vlad_url">SD.Next API URL</label> |
| 87 | <div class="flex-container flexnowrap"> | 94 | <div class="flex-container flexnowrap"> |
| @@ -421,7 +421,7 @@ function completeTtsJob() { | |||
| 421 | async function tts(text, voiceId, char) { | 421 | async function tts(text, voiceId, char) { |
| 422 | async function processResponse(response) { | 422 | async function processResponse(response) { |
| 423 | // RVC injection | 423 | // RVC injection |
| 424 | if (extension_settings.rvc.enabled && typeof window['rvcVoiceConversion'] === 'function') | 424 | if (typeof window['rvcVoiceConversion'] === 'function' && extension_settings.rvc.enabled) |
| 425 | response = await window['rvcVoiceConversion'](response, char, text); | 425 | response = await window['rvcVoiceConversion'](response, char, text); |
| 426 | 426 | ||
| 427 | await addAudioJob(response, char); | 427 | await addAudioJob(response, char); |
| @@ -755,6 +755,11 @@ async function onMessageEvent(messageId, lastCharIndex) { | |||
| 755 | const message = structuredClone(context.chat[messageId]); | 755 | const message = structuredClone(context.chat[messageId]); |
| 756 | const hashNew = getStringHash(message?.mes ?? ''); | 756 | const hashNew = getStringHash(message?.mes ?? ''); |
| 757 | 757 | ||
| 758 | // Ignore prompt-hidden messages | ||
| 759 | if (message.is_system) { | ||
| 760 | return; | ||
| 761 | } | ||
| 762 | |||
| 758 | // if no new messages, or same message, or same message hash, do nothing | 763 | // if no new messages, or same message, or same message hash, do nothing |
| 759 | if (hashNew === lastMessageHash) { | 764 | if (hashNew === lastMessageHash) { |
| 760 | return; | 765 | return; |
| @@ -12,7 +12,7 @@ | |||
| 12 | <select id="vectors_source" class="text_pole"> | 12 | <select id="vectors_source" class="text_pole"> |
| 13 | <option value="cohere">Cohere</option> | 13 | <option value="cohere">Cohere</option> |
| 14 | <option value="extras">Extras</option> | 14 | <option value="extras">Extras</option> |
| 15 | <option value="palm">Google MakerSuite</option> | 15 | <option value="palm">Google AI Studio</option> |
| 16 | <option value="llamacpp">llama.cpp</option> | 16 | <option value="llamacpp">llama.cpp</option> |
| 17 | <option value="transformers" data-i18n="Local (Transformers)">Local (Transformers)</option> | 17 | <option value="transformers" data-i18n="Local (Transformers)">Local (Transformers)</option> |
| 18 | <option value="mistral">MistralAI</option> | 18 | <option value="mistral">MistralAI</option> |
| @@ -78,6 +78,19 @@ export function getKayraMaxContextTokens() { | |||
| 78 | return null; | 78 | return null; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | export function getKayraMaxResponseTokens() { | ||
| 82 | switch (novel_data?.tier) { | ||
| 83 | case 1: | ||
| 84 | return 100; | ||
| 85 | case 2: | ||
| 86 | return 100; | ||
| 87 | case 3: | ||
| 88 | return 150; | ||
| 89 | } | ||
| 90 | |||
| 91 | return maximum_output_length; | ||
| 92 | } | ||
| 93 | |||
| 81 | export function getNovelTier() { | 94 | export function getNovelTier() { |
| 82 | return nai_tiers[novel_data?.tier] ?? 'no_connection'; | 95 | return nai_tiers[novel_data?.tier] ?? 'no_connection'; |
| 83 | } | 96 | } |
| @@ -438,12 +451,14 @@ export function getNovelGenerationData(finalPrompt, settings, maxLength, isImper | |||
| 438 | console.log(finalPrompt); | 451 | console.log(finalPrompt); |
| 439 | } | 452 | } |
| 440 | 453 | ||
| 454 | const adjustedMaxLength = nai_settings.model_novel.includes('kayra') ? getKayraMaxResponseTokens() : maximum_output_length; | ||
| 455 | |||
| 441 | return { | 456 | return { |
| 442 | 'input': finalPrompt, | 457 | 'input': finalPrompt, |
| 443 | 'model': nai_settings.model_novel, | 458 | 'model': nai_settings.model_novel, |
| 444 | 'use_string': true, | 459 | 'use_string': true, |
| 445 | 'temperature': Number(nai_settings.temperature), | 460 | 'temperature': Number(nai_settings.temperature), |
| 446 | 'max_length': maxLength < maximum_output_length ? maxLength : maximum_output_length, | 461 | 'max_length': maxLength < adjustedMaxLength ? maxLength : adjustedMaxLength, |
| 447 | 'min_length': Number(nai_settings.min_length), | 462 | 'min_length': Number(nai_settings.min_length), |
| 448 | 'tail_free_sampling': Number(nai_settings.tail_free_sampling), | 463 | 'tail_free_sampling': Number(nai_settings.tail_free_sampling), |
| 449 | 'repetition_penalty': Number(nai_settings.repetition_penalty), | 464 | 'repetition_penalty': Number(nai_settings.repetition_penalty), |
| @@ -74,6 +74,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument } from './slash-commands/SlashComma | |||
| 74 | import { renderTemplateAsync } from './templates.js'; | 74 | import { renderTemplateAsync } from './templates.js'; |
| 75 | import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js'; | 75 | import { SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js'; |
| 76 | import { Popup, POPUP_RESULT } from './popup.js'; | 76 | import { Popup, POPUP_RESULT } from './popup.js'; |
| 77 | import { t } from './i18n.js'; | ||
| 77 | 78 | ||
| 78 | export { | 79 | export { |
| 79 | openai_messages_count, | 80 | openai_messages_count, |
| @@ -132,13 +133,9 @@ const max_2mil = 2000 * 1000; | |||
| 132 | const scale_max = 8191; | 133 | const scale_max = 8191; |
| 133 | const claude_max = 9000; // We have a proper tokenizer, so theoretically could be larger (up to 9k) | 134 | const claude_max = 9000; // We have a proper tokenizer, so theoretically could be larger (up to 9k) |
| 134 | const claude_100k_max = 99000; | 135 | const claude_100k_max = 99000; |
| 135 | let ai21_max = 9200; //can easily fit 9k gpt tokens because j2's tokenizer is efficient af | 136 | const unlocked_max = max_2mil; |
| 136 | const unlocked_max = max_200k; | ||
| 137 | const oai_max_temp = 2.0; | 137 | const oai_max_temp = 2.0; |
| 138 | const claude_max_temp = 1.0; //same as j2 | 138 | const claude_max_temp = 1.0; |
| 139 | const j2_max_topk = 10.0; | ||
| 140 | const j2_max_freq = 5.0; | ||
| 141 | const j2_max_pres = 5.0; | ||
| 142 | const openrouter_website_model = 'OR_Website'; | 139 | const openrouter_website_model = 'OR_Website'; |
| 143 | const openai_max_stop_strings = 4; | 140 | const openai_max_stop_strings = 4; |
| 144 | 141 | ||
| @@ -218,25 +215,11 @@ const sensitiveFields = [ | |||
| 218 | 'custom_include_headers', | 215 | 'custom_include_headers', |
| 219 | ]; | 216 | ]; |
| 220 | 217 | ||
| 221 | function getPrefixMap() { | ||
| 222 | return selected_group ? { | ||
| 223 | assistant: '', | ||
| 224 | user: '', | ||
| 225 | system: 'OOC: ', | ||
| 226 | } | ||
| 227 | : { | ||
| 228 | assistant: '{{char}}:', | ||
| 229 | user: '{{user}}:', | ||
| 230 | system: '', | ||
| 231 | }; | ||
| 232 | } | ||
| 233 | |||
| 234 | const default_settings = { | 218 | const default_settings = { |
| 235 | preset_settings_openai: 'Default', | 219 | preset_settings_openai: 'Default', |
| 236 | temp_openai: 1.0, | 220 | temp_openai: 1.0, |
| 237 | freq_pen_openai: 0, | 221 | freq_pen_openai: 0, |
| 238 | pres_pen_openai: 0, | 222 | pres_pen_openai: 0, |
| 239 | count_pen: 0.0, | ||
| 240 | top_p_openai: 1.0, | 223 | top_p_openai: 1.0, |
| 241 | top_k_openai: 0, | 224 | top_k_openai: 0, |
| 242 | min_p_openai: 0, | 225 | min_p_openai: 0, |
| @@ -264,7 +247,7 @@ const default_settings = { | |||
| 264 | openai_model: 'gpt-4-turbo', | 247 | openai_model: 'gpt-4-turbo', |
| 265 | claude_model: 'claude-3-5-sonnet-20240620', | 248 | claude_model: 'claude-3-5-sonnet-20240620', |
| 266 | google_model: 'gemini-1.5-pro', | 249 | google_model: 'gemini-1.5-pro', |
| 267 | ai21_model: 'j2-ultra', | 250 | ai21_model: 'jamba-1.5-large', |
| 268 | mistralai_model: 'mistral-large-latest', | 251 | mistralai_model: 'mistral-large-latest', |
| 269 | cohere_model: 'command-r-plus', | 252 | cohere_model: 'command-r-plus', |
| 270 | perplexity_model: 'llama-3.1-70b-instruct', | 253 | perplexity_model: 'llama-3.1-70b-instruct', |
| @@ -294,8 +277,6 @@ const default_settings = { | |||
| 294 | assistant_prefill: '', | 277 | assistant_prefill: '', |
| 295 | assistant_impersonation: '', | 278 | assistant_impersonation: '', |
| 296 | human_sysprompt_message: default_claude_human_sysprompt_message, | 279 | human_sysprompt_message: default_claude_human_sysprompt_message, |
| 297 | use_ai21_tokenizer: false, | ||
| 298 | use_google_tokenizer: false, | ||
| 299 | claude_use_sysprompt: false, | 280 | claude_use_sysprompt: false, |
| 300 | use_makersuite_sysprompt: true, | 281 | use_makersuite_sysprompt: true, |
| 301 | use_alt_scale: false, | 282 | use_alt_scale: false, |
| @@ -317,7 +298,6 @@ const oai_settings = { | |||
| 317 | temp_openai: 1.0, | 298 | temp_openai: 1.0, |
| 318 | freq_pen_openai: 0, | 299 | freq_pen_openai: 0, |
| 319 | pres_pen_openai: 0, | 300 | pres_pen_openai: 0, |
| 320 | count_pen: 0.0, | ||
| 321 | top_p_openai: 1.0, | 301 | top_p_openai: 1.0, |
| 322 | top_k_openai: 0, | 302 | top_k_openai: 0, |
| 323 | min_p_openai: 0, | 303 | min_p_openai: 0, |
| @@ -345,7 +325,7 @@ const oai_settings = { | |||
| 345 | openai_model: 'gpt-4-turbo', | 325 | openai_model: 'gpt-4-turbo', |
| 346 | claude_model: 'claude-3-5-sonnet-20240620', | 326 | claude_model: 'claude-3-5-sonnet-20240620', |
| 347 | google_model: 'gemini-1.5-pro', | 327 | google_model: 'gemini-1.5-pro', |
| 348 | ai21_model: 'j2-ultra', | 328 | ai21_model: 'jamba-1.5-large', |
| 349 | mistralai_model: 'mistral-large-latest', | 329 | mistralai_model: 'mistral-large-latest', |
| 350 | cohere_model: 'command-r-plus', | 330 | cohere_model: 'command-r-plus', |
| 351 | perplexity_model: 'llama-3.1-70b-instruct', | 331 | perplexity_model: 'llama-3.1-70b-instruct', |
| @@ -375,8 +355,6 @@ const oai_settings = { | |||
| 375 | assistant_prefill: '', | 355 | assistant_prefill: '', |
| 376 | assistant_impersonation: '', | 356 | assistant_impersonation: '', |
| 377 | human_sysprompt_message: default_claude_human_sysprompt_message, | 357 | human_sysprompt_message: default_claude_human_sysprompt_message, |
| 378 | use_ai21_tokenizer: false, | ||
| 379 | use_google_tokenizer: false, | ||
| 380 | claude_use_sysprompt: false, | 358 | claude_use_sysprompt: false, |
| 381 | use_makersuite_sysprompt: true, | 359 | use_makersuite_sysprompt: true, |
| 382 | use_alt_scale: false, | 360 | use_alt_scale: false, |
| @@ -425,7 +403,7 @@ async function validateReverseProxy() { | |||
| 425 | const rememberKey = `Proxy_SkipConfirm_${getStringHash(oai_settings.reverse_proxy)}`; | 403 | const rememberKey = `Proxy_SkipConfirm_${getStringHash(oai_settings.reverse_proxy)}`; |
| 426 | const skipConfirm = localStorage.getItem(rememberKey) === 'true'; | 404 | const skipConfirm = localStorage.getItem(rememberKey) === 'true'; |
| 427 | 405 | ||
| 428 | const confirmation = skipConfirm || await Popup.show.confirm('Connecting To Proxy', `<span>Are you sure you want to connect to the following proxy URL?</span><var>${DOMPurify.sanitize(oai_settings.reverse_proxy)}</var>`); | 406 | const confirmation = skipConfirm || await Popup.show.confirm(t`Connecting To Proxy`, await renderTemplateAsync('proxyConnectionWarning', { proxyURL: DOMPurify.sanitize(oai_settings.reverse_proxy) })); |
| 429 | 407 | ||
| 430 | if (!confirmation) { | 408 | if (!confirmation) { |
| 431 | toastr.error('Update or remove your reverse proxy settings.'); | 409 | toastr.error('Update or remove your reverse proxy settings.'); |
| @@ -1148,7 +1126,6 @@ function preparePromptsForChatCompletion({ Scenario, charPersonality, name2, wor | |||
| 1148 | { role: 'system', content: charDescription, identifier: 'charDescription' }, | 1126 | { role: 'system', content: charDescription, identifier: 'charDescription' }, |
| 1149 | { role: 'system', content: charPersonalityText, identifier: 'charPersonality' }, | 1127 | { role: 'system', content: charPersonalityText, identifier: 'charPersonality' }, |
| 1150 | { role: 'system', content: scenarioText, identifier: 'scenario' }, | 1128 | { role: 'system', content: scenarioText, identifier: 'scenario' }, |
| 1151 | { role: 'system', content: personaDescription, identifier: 'personaDescription' }, | ||
| 1152 | // Unordered prompts without marker | 1129 | // Unordered prompts without marker |
| 1153 | { role: 'system', content: impersonationPrompt, identifier: 'impersonate' }, | 1130 | { role: 'system', content: impersonationPrompt, identifier: 'impersonate' }, |
| 1154 | { role: 'system', content: quietPrompt, identifier: 'quietPrompt' }, | 1131 | { role: 'system', content: quietPrompt, identifier: 'quietPrompt' }, |
| @@ -1395,6 +1372,11 @@ function tryParseStreamingError(response, decoded) { | |||
| 1395 | toastr.error(data.error.message || response.statusText, 'Chat Completion API'); | 1372 | toastr.error(data.error.message || response.statusText, 'Chat Completion API'); |
| 1396 | throw new Error(data); | 1373 | throw new Error(data); |
| 1397 | } | 1374 | } |
| 1375 | |||
| 1376 | if (data.message) { | ||
| 1377 | toastr.error(data.message, 'Chat Completion API'); | ||
| 1378 | throw new Error(data); | ||
| 1379 | } | ||
| 1398 | } | 1380 | } |
| 1399 | catch { | 1381 | catch { |
| 1400 | // No JSON. Do nothing. | 1382 | // No JSON. Do nothing. |
| @@ -1802,7 +1784,6 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 1802 | const isClaude = oai_settings.chat_completion_source == chat_completion_sources.CLAUDE; | 1784 | const isClaude = oai_settings.chat_completion_source == chat_completion_sources.CLAUDE; |
| 1803 | const isOpenRouter = oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER; | 1785 | const isOpenRouter = oai_settings.chat_completion_source == chat_completion_sources.OPENROUTER; |
| 1804 | const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE; | 1786 | const isScale = oai_settings.chat_completion_source == chat_completion_sources.SCALE; |
| 1805 | const isAI21 = oai_settings.chat_completion_source == chat_completion_sources.AI21; | ||
| 1806 | const isGoogle = oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE; | 1787 | const isGoogle = oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE; |
| 1807 | const isOAI = oai_settings.chat_completion_source == chat_completion_sources.OPENAI; | 1788 | const isOAI = oai_settings.chat_completion_source == chat_completion_sources.OPENAI; |
| 1808 | const isMistral = oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI; | 1789 | const isMistral = oai_settings.chat_completion_source == chat_completion_sources.MISTRALAI; |
| @@ -1815,7 +1796,7 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 1815 | const isQuiet = type === 'quiet'; | 1796 | const isQuiet = type === 'quiet'; |
| 1816 | const isImpersonate = type === 'impersonate'; | 1797 | const isImpersonate = type === 'impersonate'; |
| 1817 | const isContinue = type === 'continue'; | 1798 | const isContinue = type === 'continue'; |
| 1818 | const stream = oai_settings.stream_openai && !isQuiet && !isScale && !isAI21 && !(isGoogle && oai_settings.google_model.includes('bison')); | 1799 | const stream = oai_settings.stream_openai && !isQuiet && !isScale && !(isGoogle && oai_settings.google_model.includes('bison')); |
| 1819 | const useLogprobs = !!power_user.request_token_probabilities; | 1800 | const useLogprobs = !!power_user.request_token_probabilities; |
| 1820 | const canMultiSwipe = oai_settings.n > 1 && !isContinue && !isImpersonate && !isQuiet && (isOAI || isCustom); | 1801 | const canMultiSwipe = oai_settings.n > 1 && !isContinue && !isImpersonate && !isQuiet && (isOAI || isCustom); |
| 1821 | 1802 | ||
| @@ -1824,15 +1805,6 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 1824 | replaceItemizedPromptText(messageId, messages); | 1805 | replaceItemizedPromptText(messageId, messages); |
| 1825 | } | 1806 | } |
| 1826 | 1807 | ||
| 1827 | if (isAI21) { | ||
| 1828 | const joinedMsgs = messages.reduce((acc, obj) => { | ||
| 1829 | const prefix = getPrefixMap()[obj.role]; | ||
| 1830 | return acc + (prefix ? (selected_group ? '\n' : prefix + ' ') : '') + obj.content + '\n'; | ||
| 1831 | }, ''); | ||
| 1832 | messages = substituteParams(joinedMsgs) + (isImpersonate ? `${name1}:` : `${name2}:`); | ||
| 1833 | replaceItemizedPromptText(messageId, messages); | ||
| 1834 | } | ||
| 1835 | |||
| 1836 | // If we're using the window.ai extension, use that instead | 1808 | // If we're using the window.ai extension, use that instead |
| 1837 | // Doesn't support logit bias yet | 1809 | // Doesn't support logit bias yet |
| 1838 | if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI) { | 1810 | if (oai_settings.chat_completion_source == chat_completion_sources.WINDOWAI) { |
| @@ -1931,12 +1903,6 @@ async function sendOpenAIRequest(type, messages, signal) { | |||
| 1931 | generate_data['use_makersuite_sysprompt'] = oai_settings.use_makersuite_sysprompt; | 1903 | generate_data['use_makersuite_sysprompt'] = oai_settings.use_makersuite_sysprompt; |
| 1932 | } | 1904 | } |
| 1933 | 1905 | ||
| 1934 | if (isAI21) { | ||
| 1935 | generate_data['top_k'] = Number(oai_settings.top_k_openai); | ||
| 1936 | generate_data['count_pen'] = Number(oai_settings.count_pen); | ||
| 1937 | generate_data['stop_tokens'] = [name1 + ':', substituteParams(oai_settings.new_chat_prompt), substituteParams(oai_settings.new_group_chat_prompt)]; | ||
| 1938 | } | ||
| 1939 | |||
| 1940 | if (isMistral) { | 1906 | if (isMistral) { |
| 1941 | generate_data['safe_prompt'] = false; // already defaults to false, but just incase they change that in the future. | 1907 | generate_data['safe_prompt'] = false; // already defaults to false, but just incase they change that in the future. |
| 1942 | } | 1908 | } |
| @@ -3008,7 +2974,6 @@ function loadOpenAISettings(data, settings) { | |||
| 3008 | oai_settings.temp_openai = settings.temp_openai ?? default_settings.temp_openai; | 2974 | oai_settings.temp_openai = settings.temp_openai ?? default_settings.temp_openai; |
| 3009 | oai_settings.freq_pen_openai = settings.freq_pen_openai ?? default_settings.freq_pen_openai; | 2975 | oai_settings.freq_pen_openai = settings.freq_pen_openai ?? default_settings.freq_pen_openai; |
| 3010 | oai_settings.pres_pen_openai = settings.pres_pen_openai ?? default_settings.pres_pen_openai; | 2976 | oai_settings.pres_pen_openai = settings.pres_pen_openai ?? default_settings.pres_pen_openai; |
| 3011 | oai_settings.count_pen = settings.count_pen ?? default_settings.count_pen; | ||
| 3012 | oai_settings.top_p_openai = settings.top_p_openai ?? default_settings.top_p_openai; | 2977 | oai_settings.top_p_openai = settings.top_p_openai ?? default_settings.top_p_openai; |
| 3013 | oai_settings.top_k_openai = settings.top_k_openai ?? default_settings.top_k_openai; | 2978 | oai_settings.top_k_openai = settings.top_k_openai ?? default_settings.top_k_openai; |
| 3014 | oai_settings.top_a_openai = settings.top_a_openai ?? default_settings.top_a_openai; | 2979 | oai_settings.top_a_openai = settings.top_a_openai ?? default_settings.top_a_openai; |
| @@ -3080,10 +3045,12 @@ function loadOpenAISettings(data, settings) { | |||
| 3080 | oai_settings.names_behavior = character_names_behavior.COMPLETION; | 3045 | oai_settings.names_behavior = character_names_behavior.COMPLETION; |
| 3081 | } | 3046 | } |
| 3082 | 3047 | ||
| 3048 | if (oai_settings.ai21_model.startsWith('j2-')) { | ||
| 3049 | oai_settings.ai21_model = 'jamba-1.5-large'; | ||
| 3050 | } | ||
| 3051 | |||
| 3083 | if (settings.wrap_in_quotes !== undefined) oai_settings.wrap_in_quotes = !!settings.wrap_in_quotes; | 3052 | if (settings.wrap_in_quotes !== undefined) oai_settings.wrap_in_quotes = !!settings.wrap_in_quotes; |
| 3084 | if (settings.openai_model !== undefined) oai_settings.openai_model = settings.openai_model; | 3053 | if (settings.openai_model !== undefined) oai_settings.openai_model = settings.openai_model; |
| 3085 | if (settings.use_ai21_tokenizer !== undefined) { oai_settings.use_ai21_tokenizer = !!settings.use_ai21_tokenizer; oai_settings.use_ai21_tokenizer ? ai21_max = 8191 : ai21_max = 9200; } | ||
| 3086 | if (settings.use_google_tokenizer !== undefined) oai_settings.use_google_tokenizer = !!settings.use_google_tokenizer; | ||
| 3087 | if (settings.claude_use_sysprompt !== undefined) oai_settings.claude_use_sysprompt = !!settings.claude_use_sysprompt; | 3054 | if (settings.claude_use_sysprompt !== undefined) oai_settings.claude_use_sysprompt = !!settings.claude_use_sysprompt; |
| 3088 | if (settings.use_makersuite_sysprompt !== undefined) oai_settings.use_makersuite_sysprompt = !!settings.use_makersuite_sysprompt; | 3055 | if (settings.use_makersuite_sysprompt !== undefined) oai_settings.use_makersuite_sysprompt = !!settings.use_makersuite_sysprompt; |
| 3089 | if (settings.use_alt_scale !== undefined) { oai_settings.use_alt_scale = !!settings.use_alt_scale; updateScaleForm(); } | 3056 | if (settings.use_alt_scale !== undefined) { oai_settings.use_alt_scale = !!settings.use_alt_scale; updateScaleForm(); } |
| @@ -3133,8 +3100,6 @@ function loadOpenAISettings(data, settings) { | |||
| 3133 | $('#jailbreak_system').prop('checked', oai_settings.jailbreak_system); | 3100 | $('#jailbreak_system').prop('checked', oai_settings.jailbreak_system); |
| 3134 | $('#openai_show_external_models').prop('checked', oai_settings.show_external_models); | 3101 | $('#openai_show_external_models').prop('checked', oai_settings.show_external_models); |
| 3135 | $('#openai_external_category').toggle(oai_settings.show_external_models); | 3102 | $('#openai_external_category').toggle(oai_settings.show_external_models); |
| 3136 | $('#use_ai21_tokenizer').prop('checked', oai_settings.use_ai21_tokenizer); | ||
| 3137 | $('#use_google_tokenizer').prop('checked', oai_settings.use_google_tokenizer); | ||
| 3138 | $('#claude_use_sysprompt').prop('checked', oai_settings.claude_use_sysprompt); | 3103 | $('#claude_use_sysprompt').prop('checked', oai_settings.claude_use_sysprompt); |
| 3139 | $('#use_makersuite_sysprompt').prop('checked', oai_settings.use_makersuite_sysprompt); | 3104 | $('#use_makersuite_sysprompt').prop('checked', oai_settings.use_makersuite_sysprompt); |
| 3140 | $('#scale-alt').prop('checked', oai_settings.use_alt_scale); | 3105 | $('#scale-alt').prop('checked', oai_settings.use_alt_scale); |
| @@ -3170,9 +3135,6 @@ function loadOpenAISettings(data, settings) { | |||
| 3170 | $('#pres_pen_openai').val(oai_settings.pres_pen_openai); | 3135 | $('#pres_pen_openai').val(oai_settings.pres_pen_openai); |
| 3171 | $('#pres_pen_counter_openai').val(Number(oai_settings.pres_pen_openai).toFixed(2)); | 3136 | $('#pres_pen_counter_openai').val(Number(oai_settings.pres_pen_openai).toFixed(2)); |
| 3172 | 3137 | ||
| 3173 | $('#count_pen').val(oai_settings.count_pen); | ||
| 3174 | $('#count_pen_counter').val(Number(oai_settings.count_pen).toFixed(2)); | ||
| 3175 | |||
| 3176 | $('#top_p_openai').val(oai_settings.top_p_openai); | 3138 | $('#top_p_openai').val(oai_settings.top_p_openai); |
| 3177 | $('#top_p_counter_openai').val(Number(oai_settings.top_p_openai).toFixed(2)); | 3139 | $('#top_p_counter_openai').val(Number(oai_settings.top_p_openai).toFixed(2)); |
| 3178 | 3140 | ||
| @@ -3392,7 +3354,6 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | |||
| 3392 | temperature: settings.temp_openai, | 3354 | temperature: settings.temp_openai, |
| 3393 | frequency_penalty: settings.freq_pen_openai, | 3355 | frequency_penalty: settings.freq_pen_openai, |
| 3394 | presence_penalty: settings.pres_pen_openai, | 3356 | presence_penalty: settings.pres_pen_openai, |
| 3395 | count_penalty: settings.count_pen, | ||
| 3396 | top_p: settings.top_p_openai, | 3357 | top_p: settings.top_p_openai, |
| 3397 | top_k: settings.top_k_openai, | 3358 | top_k: settings.top_k_openai, |
| 3398 | top_a: settings.top_a_openai, | 3359 | top_a: settings.top_a_openai, |
| @@ -3427,8 +3388,6 @@ async function saveOpenAIPreset(name, settings, triggerUi = true) { | |||
| 3427 | assistant_prefill: settings.assistant_prefill, | 3388 | assistant_prefill: settings.assistant_prefill, |
| 3428 | assistant_impersonation: settings.assistant_impersonation, | 3389 | assistant_impersonation: settings.assistant_impersonation, |
| 3429 | human_sysprompt_message: settings.human_sysprompt_message, | 3390 | human_sysprompt_message: settings.human_sysprompt_message, |
| 3430 | use_ai21_tokenizer: settings.use_ai21_tokenizer, | ||
| 3431 | use_google_tokenizer: settings.use_google_tokenizer, | ||
| 3432 | claude_use_sysprompt: settings.claude_use_sysprompt, | 3391 | claude_use_sysprompt: settings.claude_use_sysprompt, |
| 3433 | use_makersuite_sysprompt: settings.use_makersuite_sysprompt, | 3392 | use_makersuite_sysprompt: settings.use_makersuite_sysprompt, |
| 3434 | use_alt_scale: settings.use_alt_scale, | 3393 | use_alt_scale: settings.use_alt_scale, |
| @@ -3799,7 +3758,6 @@ function onSettingsPresetChange() { | |||
| 3799 | temperature: ['#temp_openai', 'temp_openai', false], | 3758 | temperature: ['#temp_openai', 'temp_openai', false], |
| 3800 | frequency_penalty: ['#freq_pen_openai', 'freq_pen_openai', false], | 3759 | frequency_penalty: ['#freq_pen_openai', 'freq_pen_openai', false], |
| 3801 | presence_penalty: ['#pres_pen_openai', 'pres_pen_openai', false], | 3760 | presence_penalty: ['#pres_pen_openai', 'pres_pen_openai', false], |
| 3802 | count_penalty: ['#count_pen', 'count_pen', false], | ||
| 3803 | top_p: ['#top_p_openai', 'top_p_openai', false], | 3761 | top_p: ['#top_p_openai', 'top_p_openai', false], |
| 3804 | top_k: ['#top_k_openai', 'top_k_openai', false], | 3762 | top_k: ['#top_k_openai', 'top_k_openai', false], |
| 3805 | top_a: ['#top_a_openai', 'top_a_openai', false], | 3763 | top_a: ['#top_a_openai', 'top_a_openai', false], |
| @@ -3856,8 +3814,6 @@ function onSettingsPresetChange() { | |||
| 3856 | assistant_prefill: ['#claude_assistant_prefill', 'assistant_prefill', false], | 3814 | assistant_prefill: ['#claude_assistant_prefill', 'assistant_prefill', false], |
| 3857 | assistant_impersonation: ['#claude_assistant_impersonation', 'assistant_impersonation', false], | 3815 | assistant_impersonation: ['#claude_assistant_impersonation', 'assistant_impersonation', false], |
| 3858 | human_sysprompt_message: ['#claude_human_sysprompt_textarea', 'human_sysprompt_message', false], | 3816 | human_sysprompt_message: ['#claude_human_sysprompt_textarea', 'human_sysprompt_message', false], |
| 3859 | use_ai21_tokenizer: ['#use_ai21_tokenizer', 'use_ai21_tokenizer', true], | ||
| 3860 | use_google_tokenizer: ['#use_google_tokenizer', 'use_google_tokenizer', true], | ||
| 3861 | claude_use_sysprompt: ['#claude_use_sysprompt', 'claude_use_sysprompt', true], | 3817 | claude_use_sysprompt: ['#claude_use_sysprompt', 'claude_use_sysprompt', true], |
| 3862 | use_makersuite_sysprompt: ['#use_makersuite_sysprompt', 'use_makersuite_sysprompt', true], | 3818 | use_makersuite_sysprompt: ['#use_makersuite_sysprompt', 'use_makersuite_sysprompt', true], |
| 3863 | use_alt_scale: ['#use_alt_scale', 'use_alt_scale', true], | 3819 | use_alt_scale: ['#use_alt_scale', 'use_alt_scale', true], |
| @@ -4028,6 +3984,11 @@ async function onModelChange() { | |||
| 4028 | } | 3984 | } |
| 4029 | 3985 | ||
| 4030 | if ($(this).is('#model_ai21_select')) { | 3986 | if ($(this).is('#model_ai21_select')) { |
| 3987 | if (value === '' || value.startsWith('j2-')) { | ||
| 3988 | value = 'jamba-1.5-large'; | ||
| 3989 | $('#model_ai21_select').val(value); | ||
| 3990 | } | ||
| 3991 | |||
| 4031 | console.log('AI21 model changed to', value); | 3992 | console.log('AI21 model changed to', value); |
| 4032 | oai_settings.ai21_model = value; | 3993 | oai_settings.ai21_model = value; |
| 4033 | } | 3994 | } |
| @@ -4230,7 +4191,7 @@ async function onModelChange() { | |||
| 4230 | else if (['command-light-nightly', 'command-nightly'].includes(oai_settings.cohere_model)) { | 4191 | else if (['command-light-nightly', 'command-nightly'].includes(oai_settings.cohere_model)) { |
| 4231 | $('#openai_max_context').attr('max', max_8k); | 4192 | $('#openai_max_context').attr('max', max_8k); |
| 4232 | } | 4193 | } |
| 4233 | else if (['command-r', 'command-r-plus'].includes(oai_settings.cohere_model)) { | 4194 | else if (oai_settings.cohere_model.includes('command-r')) { |
| 4234 | $('#openai_max_context').attr('max', max_128k); | 4195 | $('#openai_max_context').attr('max', max_128k); |
| 4235 | } | 4196 | } |
| 4236 | else if (['c4ai-aya-23'].includes(oai_settings.cohere_model)) { | 4197 | else if (['c4ai-aya-23'].includes(oai_settings.cohere_model)) { |
| @@ -4305,33 +4266,13 @@ async function onModelChange() { | |||
| 4305 | if (oai_settings.chat_completion_source == chat_completion_sources.AI21) { | 4266 | if (oai_settings.chat_completion_source == chat_completion_sources.AI21) { |
| 4306 | if (oai_settings.max_context_unlocked) { | 4267 | if (oai_settings.max_context_unlocked) { |
| 4307 | $('#openai_max_context').attr('max', unlocked_max); | 4268 | $('#openai_max_context').attr('max', unlocked_max); |
| 4308 | } else { | 4269 | } else if (oai_settings.ai21_model.includes('jamba-1.5') || oai_settings.ai21_model.includes('jamba-instruct')) { |
| 4309 | $('#openai_max_context').attr('max', ai21_max); | 4270 | $('#openai_max_context').attr('max', max_256k); |
| 4310 | } | 4271 | } |
| 4311 | 4272 | ||
| 4312 | oai_settings.openai_max_context = Math.min(oai_settings.openai_max_context, Number($('#openai_max_context').attr('max'))); | 4273 | oai_settings.openai_max_context = Math.min(Number($('#openai_max_context').attr('max')), oai_settings.openai_max_context); |
| 4313 | $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); | 4274 | $('#openai_max_context').val(oai_settings.openai_max_context).trigger('input'); |
| 4314 | 4275 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | |
| 4315 | oai_settings.temp_openai = Math.min(claude_max_temp, oai_settings.temp_openai); | ||
| 4316 | $('#temp_openai').attr('max', claude_max_temp).val(oai_settings.temp_openai).trigger('input'); | ||
| 4317 | |||
| 4318 | oai_settings.freq_pen_openai = Math.min(j2_max_freq, oai_settings.freq_pen_openai < 0 ? 0 : oai_settings.freq_pen_openai); | ||
| 4319 | $('#freq_pen_openai').attr('min', 0).attr('max', j2_max_freq).val(oai_settings.freq_pen_openai).trigger('input'); | ||
| 4320 | |||
| 4321 | oai_settings.pres_pen_openai = Math.min(j2_max_pres, oai_settings.pres_pen_openai < 0 ? 0 : oai_settings.pres_pen_openai); | ||
| 4322 | $('#pres_pen_openai').attr('min', 0).attr('max', j2_max_pres).val(oai_settings.pres_pen_openai).trigger('input'); | ||
| 4323 | |||
| 4324 | oai_settings.top_k_openai = Math.min(j2_max_topk, oai_settings.top_k_openai); | ||
| 4325 | $('#top_k_openai').attr('max', j2_max_topk).val(oai_settings.top_k_openai).trigger('input'); | ||
| 4326 | } else if (oai_settings.chat_completion_source != chat_completion_sources.AI21) { | ||
| 4327 | oai_settings.freq_pen_openai = Math.min(2.0, oai_settings.freq_pen_openai); | ||
| 4328 | $('#freq_pen_openai').attr('min', -2.0).attr('max', 2.0).val(oai_settings.freq_pen_openai).trigger('input'); | ||
| 4329 | |||
| 4330 | oai_settings.pres_pen_openai = Math.min(2.0, oai_settings.pres_pen_openai); | ||
| 4331 | $('#pres_pen_openai').attr('min', -2.0).attr('max', 2.0).val(oai_settings.pres_pen_openai).trigger('input'); | ||
| 4332 | |||
| 4333 | oai_settings.top_k_openai = Math.min(200, oai_settings.top_k_openai); | ||
| 4334 | $('#top_k_openai').attr('max', 200).val(oai_settings.top_k_openai).trigger('input'); | ||
| 4335 | } | 4276 | } |
| 4336 | 4277 | ||
| 4337 | if (oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) { | 4278 | if (oai_settings.chat_completion_source == chat_completion_sources.CUSTOM) { |
| @@ -4388,6 +4329,16 @@ async function onModelChange() { | |||
| 4388 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); | 4329 | $('#temp_openai').attr('max', oai_max_temp).val(oai_settings.temp_openai).trigger('input'); |
| 4389 | } | 4330 | } |
| 4390 | 4331 | ||
| 4332 | if (oai_settings.chat_completion_source === chat_completion_sources.COHERE) { | ||
| 4333 | oai_settings.pres_pen_openai = Math.min(Math.max(0, oai_settings.pres_pen_openai), 1); | ||
| 4334 | $('#pres_pen_openai').attr('max', 1).attr('min', 0).val(oai_settings.pres_pen_openai).trigger('input'); | ||
| 4335 | oai_settings.freq_pen_openai = Math.min(Math.max(0, oai_settings.freq_pen_openai), 1); | ||
| 4336 | $('#freq_pen_openai').attr('max', 1).attr('min', 0).val(oai_settings.freq_pen_openai).trigger('input'); | ||
| 4337 | } else { | ||
| 4338 | $('#pres_pen_openai').attr('max', 2).attr('min', -2).val(oai_settings.pres_pen_openai).trigger('input'); | ||
| 4339 | $('#freq_pen_openai').attr('max', 2).attr('min', -2).val(oai_settings.freq_pen_openai).trigger('input'); | ||
| 4340 | } | ||
| 4341 | |||
| 4391 | $('#openai_max_context_counter').attr('max', Number($('#openai_max_context').attr('max'))); | 4342 | $('#openai_max_context_counter').attr('max', Number($('#openai_max_context').attr('max'))); |
| 4392 | 4343 | ||
| 4393 | saveSettingsDebounced(); | 4344 | saveSettingsDebounced(); |
| @@ -4473,7 +4424,7 @@ async function onConnectButtonClick(e) { | |||
| 4473 | } | 4424 | } |
| 4474 | 4425 | ||
| 4475 | if (!secret_state[SECRET_KEYS.MAKERSUITE] && !oai_settings.reverse_proxy) { | 4426 | if (!secret_state[SECRET_KEYS.MAKERSUITE] && !oai_settings.reverse_proxy) { |
| 4476 | console.log('No secret key saved for MakerSuite'); | 4427 | console.log('No secret key saved for Google AI Studio'); |
| 4477 | return; | 4428 | return; |
| 4478 | } | 4429 | } |
| 4479 | } | 4430 | } |
| @@ -4673,17 +4624,17 @@ function toggleChatCompletionForms() { | |||
| 4673 | async function testApiConnection() { | 4624 | async function testApiConnection() { |
| 4674 | // Check if the previous request is still in progress | 4625 | // Check if the previous request is still in progress |
| 4675 | if (is_send_press) { | 4626 | if (is_send_press) { |
| 4676 | toastr.info('Please wait for the previous request to complete.'); | 4627 | toastr.info(t`Please wait for the previous request to complete.`); |
| 4677 | return; | 4628 | return; |
| 4678 | } | 4629 | } |
| 4679 | 4630 | ||
| 4680 | try { | 4631 | try { |
| 4681 | const reply = await sendOpenAIRequest('quiet', [{ 'role': 'user', 'content': 'Hi' }]); | 4632 | const reply = await sendOpenAIRequest('quiet', [{ 'role': 'user', 'content': 'Hi' }]); |
| 4682 | console.log(reply); | 4633 | console.log(reply); |
| 4683 | toastr.success('API connection successful!'); | 4634 | toastr.success(t`API connection successful!`); |
| 4684 | } | 4635 | } |
| 4685 | catch (err) { | 4636 | catch (err) { |
| 4686 | toastr.error('Could not get a reply from API. Check your connection settings / API key and try again.'); | 4637 | toastr.error(t`Could not get a reply from API. Check your connection settings / API key and try again.`); |
| 4687 | } | 4638 | } |
| 4688 | } | 4639 | } |
| 4689 | 4640 | ||
| @@ -4752,11 +4703,14 @@ export function isImageInliningSupported() { | |||
| 4752 | 'gemini-1.5-flash', | 4703 | 'gemini-1.5-flash', |
| 4753 | 'gemini-1.5-flash-latest', | 4704 | 'gemini-1.5-flash-latest', |
| 4754 | 'gemini-1.5-flash-001', | 4705 | 'gemini-1.5-flash-001', |
| 4706 | 'gemini-1.5-flash-exp-0827', | ||
| 4707 | 'gemini-1.5-flash-8b-exp-0827', | ||
| 4755 | 'gemini-1.0-pro-vision-latest', | 4708 | 'gemini-1.0-pro-vision-latest', |
| 4756 | 'gemini-1.5-pro', | 4709 | 'gemini-1.5-pro', |
| 4757 | 'gemini-1.5-pro-latest', | 4710 | 'gemini-1.5-pro-latest', |
| 4758 | 'gemini-1.5-pro-001', | 4711 | 'gemini-1.5-pro-001', |
| 4759 | 'gemini-1.5-pro-exp-0801', | 4712 | 'gemini-1.5-pro-exp-0801', |
| 4713 | 'gemini-1.5-pro-exp-0827', | ||
| 4760 | 'gemini-pro-vision', | 4714 | 'gemini-pro-vision', |
| 4761 | 'claude-3', | 4715 | 'claude-3', |
| 4762 | 'claude-3-5', | 4716 | 'claude-3-5', |
| @@ -4837,7 +4791,7 @@ function onProxyPresetChange() { | |||
| 4837 | if (selectedPreset) { | 4791 | if (selectedPreset) { |
| 4838 | setProxyPreset(selectedPreset.name, selectedPreset.url, selectedPreset.password); | 4792 | setProxyPreset(selectedPreset.name, selectedPreset.url, selectedPreset.password); |
| 4839 | } else { | 4793 | } else { |
| 4840 | console.error(`Proxy preset "${value}" not found in proxies array.`); | 4794 | console.error(t`Proxy preset '${value}' not found in proxies array.`); |
| 4841 | } | 4795 | } |
| 4842 | saveSettingsDebounced(); | 4796 | saveSettingsDebounced(); |
| 4843 | } | 4797 | } |
| @@ -4849,7 +4803,7 @@ $('#save_proxy').on('click', async function () { | |||
| 4849 | 4803 | ||
| 4850 | setProxyPreset(presetName, reverseProxy, proxyPassword); | 4804 | setProxyPreset(presetName, reverseProxy, proxyPassword); |
| 4851 | saveSettingsDebounced(); | 4805 | saveSettingsDebounced(); |
| 4852 | toastr.success('Proxy Saved'); | 4806 | toastr.success(t`Proxy Saved`); |
| 4853 | if ($('#openai_proxy_preset').val() !== presetName) { | 4807 | if ($('#openai_proxy_preset').val() !== presetName) { |
| 4854 | const option = document.createElement('option'); | 4808 | const option = document.createElement('option'); |
| 4855 | option.text = presetName; | 4809 | option.text = presetName; |
| @@ -4883,9 +4837,9 @@ $('#delete_proxy').on('click', async function () { | |||
| 4883 | 4837 | ||
| 4884 | saveSettingsDebounced(); | 4838 | saveSettingsDebounced(); |
| 4885 | $('#openai_proxy_preset').val(selected_proxy.name); | 4839 | $('#openai_proxy_preset').val(selected_proxy.name); |
| 4886 | toastr.success('Proxy Deleted'); | 4840 | toastr.success(t`Proxy Deleted`); |
| 4887 | } else { | 4841 | } else { |
| 4888 | toastr.error(`Could not find proxy with name "${presetName}"`); | 4842 | toastr.error(t`Could not find proxy with name '${presetName}'`); |
| 4889 | } | 4843 | } |
| 4890 | }); | 4844 | }); |
| 4891 | 4845 | ||
| @@ -4953,12 +4907,6 @@ $(document).ready(async function () { | |||
| 4953 | saveSettingsDebounced(); | 4907 | saveSettingsDebounced(); |
| 4954 | }); | 4908 | }); |
| 4955 | 4909 | ||
| 4956 | $('#count_pen').on('input', function () { | ||
| 4957 | oai_settings.count_pen = Number($(this).val()); | ||
| 4958 | $('#count_pen_counter').val(Number($(this).val()).toFixed(2)); | ||
| 4959 | saveSettingsDebounced(); | ||
| 4960 | }); | ||
| 4961 | |||
| 4962 | $('#top_p_openai').on('input', function () { | 4910 | $('#top_p_openai').on('input', function () { |
| 4963 | oai_settings.top_p_openai = Number($(this).val()); | 4911 | oai_settings.top_p_openai = Number($(this).val()); |
| 4964 | $('#top_p_counter_openai').val(Number($(this).val()).toFixed(2)); | 4912 | $('#top_p_counter_openai').val(Number($(this).val()).toFixed(2)); |
| @@ -5017,20 +4965,6 @@ $(document).ready(async function () { | |||
| 5017 | saveSettingsDebounced(); | 4965 | saveSettingsDebounced(); |
| 5018 | }); | 4966 | }); |
| 5019 | 4967 | ||
| 5020 | $('#use_ai21_tokenizer').on('change', function () { | ||
| 5021 | oai_settings.use_ai21_tokenizer = !!$('#use_ai21_tokenizer').prop('checked'); | ||
| 5022 | oai_settings.use_ai21_tokenizer ? ai21_max = 8191 : ai21_max = 9200; | ||
| 5023 | oai_settings.openai_max_context = Math.min(ai21_max, oai_settings.openai_max_context); | ||
| 5024 | $('#openai_max_context').attr('max', ai21_max).val(oai_settings.openai_max_context).trigger('input'); | ||
| 5025 | $('#openai_max_context_counter').attr('max', Number($('#openai_max_context').attr('max'))); | ||
| 5026 | saveSettingsDebounced(); | ||
| 5027 | }); | ||
| 5028 | |||
| 5029 | $('#use_google_tokenizer').on('change', function () { | ||
| 5030 | oai_settings.use_google_tokenizer = !!$('#use_google_tokenizer').prop('checked'); | ||
| 5031 | saveSettingsDebounced(); | ||
| 5032 | }); | ||
| 5033 | |||
| 5034 | $('#claude_use_sysprompt').on('change', function () { | 4968 | $('#claude_use_sysprompt').on('change', function () { |
| 5035 | oai_settings.claude_use_sysprompt = !!$('#claude_use_sysprompt').prop('checked'); | 4969 | oai_settings.claude_use_sysprompt = !!$('#claude_use_sysprompt').prop('checked'); |
| 5036 | $('#claude_human_sysprompt_message_block').toggle(oai_settings.claude_use_sysprompt); | 4970 | $('#claude_human_sysprompt_message_block').toggle(oai_settings.claude_use_sysprompt); |
| @@ -40,8 +40,8 @@ export const POPUP_RESULT = { | |||
| 40 | * @property {POPUP_RESULT|number?} [defaultResult=POPUP_RESULT.AFFIRMATIVE] - The default result of this popup when Enter is pressed. Can be changed from `POPUP_RESULT.AFFIRMATIVE`. | 40 | * @property {POPUP_RESULT|number?} [defaultResult=POPUP_RESULT.AFFIRMATIVE] - The default result of this popup when Enter is pressed. Can be changed from `POPUP_RESULT.AFFIRMATIVE`. |
| 41 | * @property {CustomPopupButton[]|string[]?} [customButtons=null] - Custom buttons to add to the popup. If only strings are provided, the buttons will be added with default options, and their result will be in order from `2` onward. | 41 | * @property {CustomPopupButton[]|string[]?} [customButtons=null] - Custom buttons to add to the popup. If only strings are provided, the buttons will be added with default options, and their result will be in order from `2` onward. |
| 42 | * @property {CustomPopupInput[]?} [customInputs=null] - Custom inputs to add to the popup. The display below the content and the input box, one by one. | 42 | * @property {CustomPopupInput[]?} [customInputs=null] - Custom inputs to add to the popup. The display below the content and the input box, one by one. |
| 43 | * @property {(popup: Popup) => boolean?} [onClosing=null] - Handler called before the popup closes, return `false` to cancel the close | 43 | * @property {(popup: Popup) => Promise<boolean?>|boolean?} [onClosing=null] - Handler called before the popup closes, return `false` to cancel the close |
| 44 | * @property {(popup: Popup) => void?} [onClose=null] - Handler called after the popup closes, but before the DOM is cleaned up | 44 | * @property {(popup: Popup) => Promise<void?>|void?} [onClose=null] - Handler called after the popup closes, but before the DOM is cleaned up |
| 45 | * @property {number?} [cropAspect=null] - Aspect ratio for the crop popup | 45 | * @property {number?} [cropAspect=null] - Aspect ratio for the crop popup |
| 46 | * @property {string?} [cropImage=null] - Image URL to display in the crop popup | 46 | * @property {string?} [cropImage=null] - Image URL to display in the crop popup |
| 47 | */ | 47 | */ |
| @@ -138,8 +138,8 @@ export class Popup { | |||
| 138 | /** @readonly @type {CustomPopupButton[]|string[]?} */ customButtons; | 138 | /** @readonly @type {CustomPopupButton[]|string[]?} */ customButtons; |
| 139 | /** @readonly @type {CustomPopupInput[]} */ customInputs; | 139 | /** @readonly @type {CustomPopupInput[]} */ customInputs; |
| 140 | 140 | ||
| 141 | /** @type {(popup: Popup) => boolean?} */ onClosing; | 141 | /** @type {(popup: Popup) => Promise<boolean?>|boolean?} */ onClosing; |
| 142 | /** @type {(popup: Popup) => void?} */ onClose; | 142 | /** @type {(popup: Popup) => Promise<void?>|void?} */ onClose; |
| 143 | 143 | ||
| 144 | /** @type {POPUP_RESULT|number} */ result; | 144 | /** @type {POPUP_RESULT|number} */ result; |
| 145 | /** @type {any} */ value; | 145 | /** @type {any} */ value; |
| @@ -509,7 +509,7 @@ export class Popup { | |||
| 509 | this.result = result; | 509 | this.result = result; |
| 510 | 510 | ||
| 511 | if (this.onClosing) { | 511 | if (this.onClosing) { |
| 512 | const shouldClose = this.onClosing(this); | 512 | const shouldClose = await this.onClosing(this); |
| 513 | if (!shouldClose) { | 513 | if (!shouldClose) { |
| 514 | this.#isClosingPrevented = true; | 514 | this.#isClosingPrevented = true; |
| 515 | // Set values back if we cancel out of closing the popup | 515 | // Set values back if we cancel out of closing the popup |
| @@ -547,13 +547,13 @@ export class Popup { | |||
| 547 | fixToastrForDialogs(); | 547 | fixToastrForDialogs(); |
| 548 | 548 | ||
| 549 | // After the dialog is actually completely closed, remove it from the DOM | 549 | // After the dialog is actually completely closed, remove it from the DOM |
| 550 | runAfterAnimation(this.dlg, () => { | 550 | runAfterAnimation(this.dlg, async () => { |
| 551 | // Call the close on the dialog | 551 | // Call the close on the dialog |
| 552 | this.dlg.close(); | 552 | this.dlg.close(); |
| 553 | 553 | ||
| 554 | // Run a possible custom handler right before DOM removal | 554 | // Run a possible custom handler right before DOM removal |
| 555 | if (this.onClose) { | 555 | if (this.onClose) { |
| 556 | this.onClose(this); | 556 | await this.onClose(this); |
| 557 | } | 557 | } |
| 558 | 558 | ||
| 559 | // Remove it from the dom | 559 | // Remove it from the dom |
| @@ -60,6 +60,7 @@ export { | |||
| 60 | power_user, | 60 | power_user, |
| 61 | send_on_enter_options, | 61 | send_on_enter_options, |
| 62 | getContextSettings, | 62 | getContextSettings, |
| 63 | applyPowerUserSettings, | ||
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| 65 | export const MAX_CONTEXT_DEFAULT = 8192; | 66 | export const MAX_CONTEXT_DEFAULT = 8192; |
| @@ -106,6 +107,7 @@ export const persona_description_positions = { | |||
| 106 | TOP_AN: 2, | 107 | TOP_AN: 2, |
| 107 | BOTTOM_AN: 3, | 108 | BOTTOM_AN: 3, |
| 108 | AT_DEPTH: 4, | 109 | AT_DEPTH: 4, |
| 110 | NONE: 9, | ||
| 109 | }; | 111 | }; |
| 110 | 112 | ||
| 111 | let power_user = { | 113 | let power_user = { |
| @@ -301,45 +303,9 @@ let movingUIPresets = []; | |||
| 301 | export let context_presets = []; | 303 | export let context_presets = []; |
| 302 | 304 | ||
| 303 | const storage_keys = { | 305 | const storage_keys = { |
| 304 | fast_ui_mode: 'TavernAI_fast_ui_mode', | ||
| 305 | avatar_style: 'TavernAI_avatar_style', | ||
| 306 | chat_display: 'TavernAI_chat_display', | ||
| 307 | chat_width: 'chat_width', | ||
| 308 | font_scale: 'TavernAI_font_scale', | ||
| 309 | |||
| 310 | main_text_color: 'TavernAI_main_text_color', | ||
| 311 | italics_text_color: 'TavernAI_italics_text_color', | ||
| 312 | underline_text_color: 'TavernAI_underline_text_color', | ||
| 313 | quote_text_color: 'TavernAI_quote_text_color', | ||
| 314 | blur_tint_color: 'TavernAI_blur_tint_color', | ||
| 315 | chat_tint_color: 'TavernAI_chat_tint_color', | ||
| 316 | user_mes_blur_tint_color: 'TavernAI_user_mes_blur_tint_color', | ||
| 317 | bot_mes_blur_tint_color: 'TavernAI_bot_mes_blur_tint_color', | ||
| 318 | blur_strength: 'TavernAI_blur_strength', | ||
| 319 | shadow_color: 'TavernAI_shadow_color', | ||
| 320 | shadow_width: 'TavernAI_shadow_width', | ||
| 321 | border_color: 'TavernAI_border_color', | ||
| 322 | |||
| 323 | custom_css: 'TavernAI_custom_css', | ||
| 324 | |||
| 325 | waifuMode: 'TavernAI_waifuMode', | ||
| 326 | movingUI: 'TavernAI_movingUI', | ||
| 327 | noShadows: 'TavernAI_noShadows', | ||
| 328 | |||
| 329 | hotswap_enabled: 'HotswapEnabled', | ||
| 330 | timer_enabled: 'TimerEnabled', | ||
| 331 | timestamps_enabled: 'TimestampsEnabled', | ||
| 332 | timestamp_model_icon: 'TimestampModelIcon', | ||
| 333 | mesIDDisplay_enabled: 'mesIDDisplayEnabled', | ||
| 334 | hideChatAvatars_enabled: 'hideChatAvatarsEnabled', | ||
| 335 | message_token_count_enabled: 'MessageTokenCountEnabled', | ||
| 336 | expand_message_actions: 'ExpandMessageActions', | ||
| 337 | enableZenSliders: 'enableZenSliders', | ||
| 338 | enableLabMode: 'enableLabMode', | ||
| 339 | reduced_motion: 'reduced_motion', | ||
| 340 | compact_input_area: 'compact_input_area', | ||
| 341 | auto_connect_legacy: 'AutoConnectEnabled', | 306 | auto_connect_legacy: 'AutoConnectEnabled', |
| 342 | auto_load_chat_legacy: 'AutoLoadChatEnabled', | 307 | auto_load_chat_legacy: 'AutoLoadChatEnabled', |
| 308 | hideChatAvatars_legacy: 'hideChatAvatarsEnabled', | ||
| 343 | 309 | ||
| 344 | storyStringValidationCache: 'StoryStringValidationCache', | 310 | storyStringValidationCache: 'StoryStringValidationCache', |
| 345 | }; | 311 | }; |
| @@ -459,73 +425,47 @@ function fixMarkdown(text, forDisplay) { | |||
| 459 | } | 425 | } |
| 460 | 426 | ||
| 461 | function switchHotswap() { | 427 | function switchHotswap() { |
| 462 | const value = localStorage.getItem(storage_keys.hotswap_enabled); | ||
| 463 | power_user.hotswap_enabled = value === null ? true : value == 'true'; | ||
| 464 | $('body').toggleClass('no-hotswap', !power_user.hotswap_enabled); | 428 | $('body').toggleClass('no-hotswap', !power_user.hotswap_enabled); |
| 465 | $('#hotswapEnabled').prop('checked', power_user.hotswap_enabled); | 429 | $('#hotswapEnabled').prop('checked', power_user.hotswap_enabled); |
| 466 | } | 430 | } |
| 467 | 431 | ||
| 468 | function switchTimer() { | 432 | function switchTimer() { |
| 469 | const value = localStorage.getItem(storage_keys.timer_enabled); | ||
| 470 | power_user.timer_enabled = value === null ? true : value == 'true'; | ||
| 471 | $('body').toggleClass('no-timer', !power_user.timer_enabled); | 433 | $('body').toggleClass('no-timer', !power_user.timer_enabled); |
| 472 | $('#messageTimerEnabled').prop('checked', power_user.timer_enabled); | 434 | $('#messageTimerEnabled').prop('checked', power_user.timer_enabled); |
| 473 | } | 435 | } |
| 474 | 436 | ||
| 475 | function switchTimestamps() { | 437 | function switchTimestamps() { |
| 476 | const value = localStorage.getItem(storage_keys.timestamps_enabled); | ||
| 477 | power_user.timestamps_enabled = value === null ? true : value == 'true'; | ||
| 478 | $('body').toggleClass('no-timestamps', !power_user.timestamps_enabled); | 438 | $('body').toggleClass('no-timestamps', !power_user.timestamps_enabled); |
| 479 | $('#messageTimestampsEnabled').prop('checked', power_user.timestamps_enabled); | 439 | $('#messageTimestampsEnabled').prop('checked', power_user.timestamps_enabled); |
| 480 | } | 440 | } |
| 481 | 441 | ||
| 482 | function switchIcons() { | 442 | function switchIcons() { |
| 483 | const value = localStorage.getItem(storage_keys.timestamp_model_icon); | ||
| 484 | power_user.timestamp_model_icon = value === null ? true : value == 'true'; | ||
| 485 | $('body').toggleClass('no-modelIcons', !power_user.timestamp_model_icon); | 443 | $('body').toggleClass('no-modelIcons', !power_user.timestamp_model_icon); |
| 486 | $('#messageModelIconEnabled').prop('checked', power_user.timestamp_model_icon); | 444 | $('#messageModelIconEnabled').prop('checked', power_user.timestamp_model_icon); |
| 487 | } | 445 | } |
| 488 | 446 | ||
| 489 | function switchTokenCount() { | 447 | function switchTokenCount() { |
| 490 | const value = localStorage.getItem(storage_keys.message_token_count_enabled); | ||
| 491 | power_user.message_token_count_enabled = value === null ? false : value == 'true'; | ||
| 492 | $('body').toggleClass('no-tokenCount', !power_user.message_token_count_enabled); | 448 | $('body').toggleClass('no-tokenCount', !power_user.message_token_count_enabled); |
| 493 | $('#messageTokensEnabled').prop('checked', power_user.message_token_count_enabled); | 449 | $('#messageTokensEnabled').prop('checked', power_user.message_token_count_enabled); |
| 494 | } | 450 | } |
| 495 | 451 | ||
| 496 | function switchMesIDDisplay() { | 452 | function switchMesIDDisplay() { |
| 497 | const value = localStorage.getItem(storage_keys.mesIDDisplay_enabled); | ||
| 498 | power_user.mesIDDisplay_enabled = value === null ? true : value == 'true'; | ||
| 499 | /* console.log(` | ||
| 500 | localstorage value:${value}, | ||
| 501 | poweruser before:${before}, | ||
| 502 | poweruser after:${power_user.mesIDDisplay_enabled}`) */ | ||
| 503 | $('body').toggleClass('no-mesIDDisplay', !power_user.mesIDDisplay_enabled); | 453 | $('body').toggleClass('no-mesIDDisplay', !power_user.mesIDDisplay_enabled); |
| 504 | $('#mesIDDisplayEnabled').prop('checked', power_user.mesIDDisplay_enabled); | 454 | $('#mesIDDisplayEnabled').prop('checked', power_user.mesIDDisplay_enabled); |
| 505 | } | 455 | } |
| 506 | 456 | ||
| 507 | function switchHideChatAvatars() { | 457 | function switchHideChatAvatars() { |
| 508 | const value = localStorage.getItem(storage_keys.hideChatAvatars_enabled); | ||
| 509 | power_user.hideChatAvatars_enabled = value === null ? false : value == 'true'; | ||
| 510 | /*console.log(` | ||
| 511 | localstorage value:${value}, | ||
| 512 | poweruser after:${power_user.hideChatAvatars_enabled}`) | ||
| 513 | */ | ||
| 514 | $('body').toggleClass('hideChatAvatars', power_user.hideChatAvatars_enabled); | 458 | $('body').toggleClass('hideChatAvatars', power_user.hideChatAvatars_enabled); |
| 515 | $('#hideChatAvatarsEnabled').prop('checked', power_user.hideChatAvatars_enabled); | 459 | $('#hideChatAvatarsEnabled').prop('checked', power_user.hideChatAvatars_enabled); |
| 516 | } | 460 | } |
| 517 | 461 | ||
| 518 | function switchMessageActions() { | 462 | function switchMessageActions() { |
| 519 | const value = localStorage.getItem(storage_keys.expand_message_actions); | ||
| 520 | power_user.expand_message_actions = value === null ? false : value == 'true'; | ||
| 521 | $('body').toggleClass('expandMessageActions', power_user.expand_message_actions); | 463 | $('body').toggleClass('expandMessageActions', power_user.expand_message_actions); |
| 522 | $('#expandMessageActions').prop('checked', power_user.expand_message_actions); | 464 | $('#expandMessageActions').prop('checked', power_user.expand_message_actions); |
| 523 | $('.extraMesButtons, .extraMesButtonsHint').removeAttr('style'); | 465 | $('.extraMesButtons, .extraMesButtonsHint').removeAttr('style'); |
| 524 | } | 466 | } |
| 525 | 467 | ||
| 526 | function switchReducedMotion() { | 468 | function switchReducedMotion() { |
| 527 | const value = localStorage.getItem(storage_keys.reduced_motion); | ||
| 528 | power_user.reduced_motion = value === null ? false : value == 'true'; | ||
| 529 | jQuery.fx.off = power_user.reduced_motion; | 469 | jQuery.fx.off = power_user.reduced_motion; |
| 530 | const overrideDuration = power_user.reduced_motion ? 0 : ANIMATION_DURATION_DEFAULT; | 470 | const overrideDuration = power_user.reduced_motion ? 0 : ANIMATION_DURATION_DEFAULT; |
| 531 | setAnimationDuration(overrideDuration); | 471 | setAnimationDuration(overrideDuration); |
| @@ -534,8 +474,6 @@ function switchReducedMotion() { | |||
| 534 | } | 474 | } |
| 535 | 475 | ||
| 536 | function switchCompactInputArea() { | 476 | function switchCompactInputArea() { |
| 537 | const value = localStorage.getItem(storage_keys.compact_input_area); | ||
| 538 | power_user.compact_input_area = value === null ? true : value == 'true'; | ||
| 539 | $('#send_form').toggleClass('compact', power_user.compact_input_area); | 477 | $('#send_form').toggleClass('compact', power_user.compact_input_area); |
| 540 | $('#compact_input_area').prop('checked', power_user.compact_input_area); | 478 | $('#compact_input_area').prop('checked', power_user.compact_input_area); |
| 541 | } | 479 | } |
| @@ -551,8 +489,6 @@ async function switchLabMode() { | |||
| 551 | } | 489 | } |
| 552 | */ | 490 | */ |
| 553 | await delay(100); | 491 | await delay(100); |
| 554 | const value = localStorage.getItem(storage_keys.enableLabMode); | ||
| 555 | power_user.enableLabMode = value === null ? false : value == 'true'; | ||
| 556 | $('body').toggleClass('enableLabMode', power_user.enableLabMode); | 492 | $('body').toggleClass('enableLabMode', power_user.enableLabMode); |
| 557 | $('#enableLabMode').prop('checked', power_user.enableLabMode); | 493 | $('#enableLabMode').prop('checked', power_user.enableLabMode); |
| 558 | 494 | ||
| @@ -599,8 +535,6 @@ async function switchLabMode() { | |||
| 599 | 535 | ||
| 600 | async function switchZenSliders() { | 536 | async function switchZenSliders() { |
| 601 | await delay(100); | 537 | await delay(100); |
| 602 | const value = localStorage.getItem(storage_keys.enableZenSliders); | ||
| 603 | power_user.enableZenSliders = value === null ? false : value == 'true'; | ||
| 604 | $('body').toggleClass('enableZenSliders', power_user.enableZenSliders); | 538 | $('body').toggleClass('enableZenSliders', power_user.enableZenSliders); |
| 605 | $('#enableZenSliders').prop('checked', power_user.enableZenSliders); | 539 | $('#enableZenSliders').prop('checked', power_user.enableZenSliders); |
| 606 | 540 | ||
| @@ -987,8 +921,6 @@ async function CreateZenSliders(elmnt) { | |||
| 987 | } | 921 | } |
| 988 | } | 922 | } |
| 989 | function switchUiMode() { | 923 | function switchUiMode() { |
| 990 | const fastUi = localStorage.getItem(storage_keys.fast_ui_mode); | ||
| 991 | power_user.fast_ui_mode = fastUi === null ? true : fastUi == 'true'; | ||
| 992 | $('body').toggleClass('no-blur', power_user.fast_ui_mode); | 924 | $('body').toggleClass('no-blur', power_user.fast_ui_mode); |
| 993 | $('#fast_ui_mode').prop('checked', power_user.fast_ui_mode); | 925 | $('#fast_ui_mode').prop('checked', power_user.fast_ui_mode); |
| 994 | if (power_user.fast_ui_mode) { | 926 | if (power_user.fast_ui_mode) { |
| @@ -1038,8 +970,6 @@ function switchMovingUI() { | |||
| 1038 | $('.drawer-content.maximized').each(function () { | 970 | $('.drawer-content.maximized').each(function () { |
| 1039 | $(this).find('.inline-drawer-maximize').trigger('click'); | 971 | $(this).find('.inline-drawer-maximize').trigger('click'); |
| 1040 | }); | 972 | }); |
| 1041 | const movingUI = localStorage.getItem(storage_keys.movingUI); | ||
| 1042 | power_user.movingUI = movingUI === null ? false : movingUI == 'true'; | ||
| 1043 | $('body').toggleClass('movingUI', power_user.movingUI); | 973 | $('body').toggleClass('movingUI', power_user.movingUI); |
| 1044 | if (power_user.movingUI === true) { | 974 | if (power_user.movingUI === true) { |
| 1045 | initMovingUI(); | 975 | initMovingUI(); |
| @@ -1055,9 +985,7 @@ function switchMovingUI() { | |||
| 1055 | } | 985 | } |
| 1056 | } | 986 | } |
| 1057 | 987 | ||
| 1058 | function noShadows() { | 988 | function applyNoShadows() { |
| 1059 | const noShadows = localStorage.getItem(storage_keys.noShadows); | ||
| 1060 | power_user.noShadows = noShadows === null ? false : noShadows == 'true'; | ||
| 1061 | $('body').toggleClass('noShadows', power_user.noShadows); | 989 | $('body').toggleClass('noShadows', power_user.noShadows); |
| 1062 | $('#noShadowsmode').prop('checked', power_user.noShadows); | 990 | $('#noShadowsmode').prop('checked', power_user.noShadows); |
| 1063 | if (power_user.noShadows) { | 991 | if (power_user.noShadows) { |
| @@ -1071,12 +999,9 @@ function noShadows() { | |||
| 1071 | } | 999 | } |
| 1072 | 1000 | ||
| 1073 | function applyAvatarStyle() { | 1001 | function applyAvatarStyle() { |
| 1074 | power_user.avatar_style = Number(localStorage.getItem(storage_keys.avatar_style) ?? avatar_styles.ROUND); | ||
| 1075 | $('body').toggleClass('big-avatars', power_user.avatar_style === avatar_styles.RECTANGULAR); | 1002 | $('body').toggleClass('big-avatars', power_user.avatar_style === avatar_styles.RECTANGULAR); |
| 1076 | $('body').toggleClass('square-avatars', power_user.avatar_style === avatar_styles.SQUARE); | 1003 | $('body').toggleClass('square-avatars', power_user.avatar_style === avatar_styles.SQUARE); |
| 1077 | $('#avatar_style').val(power_user.avatar_style).prop('selected', true); | 1004 | $('#avatar_style').val(power_user.avatar_style).prop('selected', true); |
| 1078 | //$(`input[name="avatar_style"][value="${power_user.avatar_style}"]`).prop("checked", true); | ||
| 1079 | |||
| 1080 | } | 1005 | } |
| 1081 | 1006 | ||
| 1082 | function applyChatDisplay() { | 1007 | function applyChatDisplay() { |
| @@ -1111,8 +1036,6 @@ function applyChatDisplay() { | |||
| 1111 | } | 1036 | } |
| 1112 | 1037 | ||
| 1113 | function applyChatWidth(type) { | 1038 | function applyChatWidth(type) { |
| 1114 | power_user.chat_width = Number(localStorage.getItem(storage_keys.chat_width) ?? 50); | ||
| 1115 | |||
| 1116 | if (type === 'forced') { | 1039 | if (type === 'forced') { |
| 1117 | let r = document.documentElement; | 1040 | let r = document.documentElement; |
| 1118 | r.style.setProperty('--sheldWidth', `${power_user.chat_width}vw`); | 1041 | r.style.setProperty('--sheldWidth', `${power_user.chat_width}vw`); |
| @@ -1174,8 +1097,6 @@ async function applyThemeColor(type) { | |||
| 1174 | } | 1097 | } |
| 1175 | 1098 | ||
| 1176 | async function applyCustomCSS() { | 1099 | async function applyCustomCSS() { |
| 1177 | power_user.custom_css = String(localStorage.getItem(storage_keys.custom_css) ?? ''); | ||
| 1178 | |||
| 1179 | $('#customCSS').val(power_user.custom_css); | 1100 | $('#customCSS').val(power_user.custom_css); |
| 1180 | var styleId = 'custom-style'; | 1101 | var styleId = 'custom-style'; |
| 1181 | var style = document.getElementById(styleId); | 1102 | var style = document.getElementById(styleId); |
| @@ -1189,32 +1110,26 @@ async function applyCustomCSS() { | |||
| 1189 | } | 1110 | } |
| 1190 | 1111 | ||
| 1191 | async function applyBlurStrength() { | 1112 | async function applyBlurStrength() { |
| 1192 | power_user.blur_strength = Number(localStorage.getItem(storage_keys.blur_strength) ?? 1); | 1113 | document.documentElement.style.setProperty('--blurStrength', String(power_user.blur_strength)); |
| 1193 | document.documentElement.style.setProperty('--blurStrength', power_user.blur_strength); | ||
| 1194 | $('#blur_strength_counter').val(power_user.blur_strength); | 1114 | $('#blur_strength_counter').val(power_user.blur_strength); |
| 1195 | $('#blur_strength').val(power_user.blur_strength); | 1115 | $('#blur_strength').val(power_user.blur_strength); |
| 1196 | |||
| 1197 | |||
| 1198 | } | 1116 | } |
| 1199 | 1117 | ||
| 1200 | async function applyShadowWidth() { | 1118 | async function applyShadowWidth() { |
| 1201 | power_user.shadow_width = Number(localStorage.getItem(storage_keys.shadow_width) ?? 2); | 1119 | document.documentElement.style.setProperty('--shadowWidth', String(power_user.shadow_width)); |
| 1202 | document.documentElement.style.setProperty('--shadowWidth', power_user.shadow_width); | ||
| 1203 | $('#shadow_width_counter').val(power_user.shadow_width); | 1120 | $('#shadow_width_counter').val(power_user.shadow_width); |
| 1204 | $('#shadow_width').val(power_user.shadow_width); | 1121 | $('#shadow_width').val(power_user.shadow_width); |
| 1205 | 1122 | ||
| 1206 | } | 1123 | } |
| 1207 | 1124 | ||
| 1208 | async function applyFontScale(type) { | 1125 | async function applyFontScale(type) { |
| 1209 | |||
| 1210 | power_user.font_scale = Number(localStorage.getItem(storage_keys.font_scale) ?? 1); | ||
| 1211 | //this is to allow forced setting on page load, theme swap, etc | 1126 | //this is to allow forced setting on page load, theme swap, etc |
| 1212 | if (type === 'forced') { | 1127 | if (type === 'forced') { |
| 1213 | document.documentElement.style.setProperty('--fontScale', power_user.font_scale); | 1128 | document.documentElement.style.setProperty('--fontScale', String(power_user.font_scale)); |
| 1214 | } else { | 1129 | } else { |
| 1215 | //this is to prevent the slider from updating page in real time | 1130 | //this is to prevent the slider from updating page in real time |
| 1216 | $('#font_scale').off('mouseup touchend').on('mouseup touchend', () => { | 1131 | $('#font_scale').off('mouseup touchend').on('mouseup touchend', () => { |
| 1217 | document.documentElement.style.setProperty('--fontScale', power_user.font_scale); | 1132 | document.documentElement.style.setProperty('--fontScale', String(power_user.font_scale)); |
| 1218 | }); | 1133 | }); |
| 1219 | } | 1134 | } |
| 1220 | 1135 | ||
| @@ -1243,64 +1158,55 @@ async function applyTheme(name) { | |||
| 1243 | { | 1158 | { |
| 1244 | key: 'blur_strength', | 1159 | key: 'blur_strength', |
| 1245 | action: async () => { | 1160 | action: async () => { |
| 1246 | localStorage.setItem(storage_keys.blur_strength, power_user.blur_strength); | ||
| 1247 | await applyBlurStrength(); | 1161 | await applyBlurStrength(); |
| 1248 | }, | 1162 | }, |
| 1249 | }, | 1163 | }, |
| 1250 | { | 1164 | { |
| 1251 | key: 'custom_css', | 1165 | key: 'custom_css', |
| 1252 | action: async () => { | 1166 | action: async () => { |
| 1253 | localStorage.setItem(storage_keys.custom_css, power_user.custom_css); | ||
| 1254 | await applyCustomCSS(); | 1167 | await applyCustomCSS(); |
| 1255 | }, | 1168 | }, |
| 1256 | }, | 1169 | }, |
| 1257 | { | 1170 | { |
| 1258 | key: 'shadow_width', | 1171 | key: 'shadow_width', |
| 1259 | action: async () => { | 1172 | action: async () => { |
| 1260 | localStorage.setItem(storage_keys.shadow_width, power_user.shadow_width); | ||
| 1261 | await applyShadowWidth(); | 1173 | await applyShadowWidth(); |
| 1262 | }, | 1174 | }, |
| 1263 | }, | 1175 | }, |
| 1264 | { | 1176 | { |
| 1265 | key: 'font_scale', | 1177 | key: 'font_scale', |
| 1266 | action: async () => { | 1178 | action: async () => { |
| 1267 | localStorage.setItem(storage_keys.font_scale, power_user.font_scale); | ||
| 1268 | await applyFontScale('forced'); | 1179 | await applyFontScale('forced'); |
| 1269 | }, | 1180 | }, |
| 1270 | }, | 1181 | }, |
| 1271 | { | 1182 | { |
| 1272 | key: 'fast_ui_mode', | 1183 | key: 'fast_ui_mode', |
| 1273 | action: async () => { | 1184 | action: async () => { |
| 1274 | localStorage.setItem(storage_keys.fast_ui_mode, power_user.fast_ui_mode); | ||
| 1275 | switchUiMode(); | 1185 | switchUiMode(); |
| 1276 | }, | 1186 | }, |
| 1277 | }, | 1187 | }, |
| 1278 | { | 1188 | { |
| 1279 | key: 'waifuMode', | 1189 | key: 'waifuMode', |
| 1280 | action: async () => { | 1190 | action: async () => { |
| 1281 | localStorage.setItem(storage_keys.waifuMode, power_user.waifuMode); | ||
| 1282 | switchWaifuMode(); | 1191 | switchWaifuMode(); |
| 1283 | }, | 1192 | }, |
| 1284 | }, | 1193 | }, |
| 1285 | { | 1194 | { |
| 1286 | key: 'chat_display', | 1195 | key: 'chat_display', |
| 1287 | action: async () => { | 1196 | action: async () => { |
| 1288 | localStorage.setItem(storage_keys.chat_display, power_user.chat_display); | ||
| 1289 | applyChatDisplay(); | 1197 | applyChatDisplay(); |
| 1290 | }, | 1198 | }, |
| 1291 | }, | 1199 | }, |
| 1292 | { | 1200 | { |
| 1293 | key: 'avatar_style', | 1201 | key: 'avatar_style', |
| 1294 | action: async () => { | 1202 | action: async () => { |
| 1295 | localStorage.setItem(storage_keys.avatar_style, power_user.avatar_style); | ||
| 1296 | applyAvatarStyle(); | 1203 | applyAvatarStyle(); |
| 1297 | }, | 1204 | }, |
| 1298 | }, | 1205 | }, |
| 1299 | { | 1206 | { |
| 1300 | key: 'noShadows', | 1207 | key: 'noShadows', |
| 1301 | action: async () => { | 1208 | action: async () => { |
| 1302 | localStorage.setItem(storage_keys.noShadows, power_user.noShadows); | 1209 | applyNoShadows(); |
| 1303 | noShadows(); | ||
| 1304 | }, | 1210 | }, |
| 1305 | }, | 1211 | }, |
| 1306 | { | 1212 | { |
| @@ -1310,78 +1216,66 @@ async function applyTheme(name) { | |||
| 1310 | if (!power_user.chat_width) { | 1216 | if (!power_user.chat_width) { |
| 1311 | power_user.chat_width = 50; | 1217 | power_user.chat_width = 50; |
| 1312 | } | 1218 | } |
| 1313 | |||
| 1314 | localStorage.setItem(storage_keys.chat_width, String(power_user.chat_width)); | ||
| 1315 | applyChatWidth('forced'); | 1219 | applyChatWidth('forced'); |
| 1316 | }, | 1220 | }, |
| 1317 | }, | 1221 | }, |
| 1318 | { | 1222 | { |
| 1319 | key: 'timer_enabled', | 1223 | key: 'timer_enabled', |
| 1320 | action: async () => { | 1224 | action: async () => { |
| 1321 | localStorage.setItem(storage_keys.timer_enabled, Boolean(power_user.timer_enabled)); | ||
| 1322 | switchTimer(); | 1225 | switchTimer(); |
| 1323 | }, | 1226 | }, |
| 1324 | }, | 1227 | }, |
| 1325 | { | 1228 | { |
| 1326 | key: 'timestamps_enabled', | 1229 | key: 'timestamps_enabled', |
| 1327 | action: async () => { | 1230 | action: async () => { |
| 1328 | localStorage.setItem(storage_keys.timestamps_enabled, Boolean(power_user.timestamps_enabled)); | ||
| 1329 | switchTimestamps(); | 1231 | switchTimestamps(); |
| 1330 | }, | 1232 | }, |
| 1331 | }, | 1233 | }, |
| 1332 | { | 1234 | { |
| 1333 | key: 'timestamp_model_icon', | 1235 | key: 'timestamp_model_icon', |
| 1334 | action: async () => { | 1236 | action: async () => { |
| 1335 | localStorage.setItem(storage_keys.timestamp_model_icon, Boolean(power_user.timestamp_model_icon)); | ||
| 1336 | switchIcons(); | 1237 | switchIcons(); |
| 1337 | }, | 1238 | }, |
| 1338 | }, | 1239 | }, |
| 1339 | { | 1240 | { |
| 1340 | key: 'message_token_count_enabled', | 1241 | key: 'message_token_count_enabled', |
| 1341 | action: async () => { | 1242 | action: async () => { |
| 1342 | localStorage.setItem(storage_keys.message_token_count_enabled, Boolean(power_user.message_token_count_enabled)); | ||
| 1343 | switchTokenCount(); | 1243 | switchTokenCount(); |
| 1344 | }, | 1244 | }, |
| 1345 | }, | 1245 | }, |
| 1346 | { | 1246 | { |
| 1347 | key: 'mesIDDisplay_enabled', | 1247 | key: 'mesIDDisplay_enabled', |
| 1348 | action: async () => { | 1248 | action: async () => { |
| 1349 | localStorage.setItem(storage_keys.mesIDDisplay_enabled, Boolean(power_user.mesIDDisplay_enabled)); | ||
| 1350 | switchMesIDDisplay(); | 1249 | switchMesIDDisplay(); |
| 1351 | }, | 1250 | }, |
| 1352 | }, | 1251 | }, |
| 1353 | { | 1252 | { |
| 1354 | key: 'hideChatAvatars_enabled', | 1253 | key: 'hideChatAvatars_enabled', |
| 1355 | action: async () => { | 1254 | action: async () => { |
| 1356 | localStorage.setItem(storage_keys.hideChatAvatars_enabled, Boolean(power_user.hideChatAvatars_enabled)); | ||
| 1357 | switchHideChatAvatars(); | 1255 | switchHideChatAvatars(); |
| 1358 | }, | 1256 | }, |
| 1359 | }, | 1257 | }, |
| 1360 | { | 1258 | { |
| 1361 | key: 'expand_message_actions', | 1259 | key: 'expand_message_actions', |
| 1362 | action: async () => { | 1260 | action: async () => { |
| 1363 | localStorage.setItem(storage_keys.expand_message_actions, Boolean(power_user.expand_message_actions)); | ||
| 1364 | switchMessageActions(); | 1261 | switchMessageActions(); |
| 1365 | }, | 1262 | }, |
| 1366 | }, | 1263 | }, |
| 1367 | { | 1264 | { |
| 1368 | key: 'enableZenSliders', | 1265 | key: 'enableZenSliders', |
| 1369 | action: async () => { | 1266 | action: async () => { |
| 1370 | localStorage.setItem(storage_keys.enableZenSliders, Boolean(power_user.enableZenSliders)); | ||
| 1371 | switchMessageActions(); | 1267 | switchMessageActions(); |
| 1372 | }, | 1268 | }, |
| 1373 | }, | 1269 | }, |
| 1374 | { | 1270 | { |
| 1375 | key: 'enableLabMode', | 1271 | key: 'enableLabMode', |
| 1376 | action: async () => { | 1272 | action: async () => { |
| 1377 | localStorage.setItem(storage_keys.enableLabMode, Boolean(power_user.enableLabMode)); | ||
| 1378 | switchMessageActions(); | 1273 | switchMessageActions(); |
| 1379 | }, | 1274 | }, |
| 1380 | }, | 1275 | }, |
| 1381 | { | 1276 | { |
| 1382 | key: 'hotswap_enabled', | 1277 | key: 'hotswap_enabled', |
| 1383 | action: async () => { | 1278 | action: async () => { |
| 1384 | localStorage.setItem(storage_keys.hotswap_enabled, Boolean(power_user.hotswap_enabled)); | ||
| 1385 | switchHotswap(); | 1279 | switchHotswap(); |
| 1386 | }, | 1280 | }, |
| 1387 | }, | 1281 | }, |
| @@ -1402,7 +1296,6 @@ async function applyTheme(name) { | |||
| 1402 | { | 1296 | { |
| 1403 | key: 'reduced_motion', | 1297 | key: 'reduced_motion', |
| 1404 | action: async () => { | 1298 | action: async () => { |
| 1405 | localStorage.setItem(storage_keys.reduced_motion, String(power_user.reduced_motion)); | ||
| 1406 | $('#reduced_motion').prop('checked', power_user.reduced_motion); | 1299 | $('#reduced_motion').prop('checked', power_user.reduced_motion); |
| 1407 | switchReducedMotion(); | 1300 | switchReducedMotion(); |
| 1408 | }, | 1301 | }, |
| @@ -1410,7 +1303,6 @@ async function applyTheme(name) { | |||
| 1410 | { | 1303 | { |
| 1411 | key: 'compact_input_area', | 1304 | key: 'compact_input_area', |
| 1412 | action: async () => { | 1305 | action: async () => { |
| 1413 | localStorage.setItem(storage_keys.compact_input_area, String(power_user.compact_input_area)); | ||
| 1414 | $('#compact_input_area').prop('checked', power_user.compact_input_area); | 1306 | $('#compact_input_area').prop('checked', power_user.compact_input_area); |
| 1415 | switchCompactInputArea(); | 1307 | switchCompactInputArea(); |
| 1416 | }, | 1308 | }, |
| @@ -1465,6 +1357,7 @@ async function showDebugMenu() { | |||
| 1465 | callGenericPopup(template, POPUP_TYPE.TEXT, '', { wide: true, large: true, allowVerticalScrolling: true }); | 1357 | callGenericPopup(template, POPUP_TYPE.TEXT, '', { wide: true, large: true, allowVerticalScrolling: true }); |
| 1466 | } | 1358 | } |
| 1467 | 1359 | ||
| 1360 | function applyPowerUserSettings() { | ||
| 1468 | switchUiMode(); | 1361 | switchUiMode(); |
| 1469 | applyFontScale('forced'); | 1362 | applyFontScale('forced'); |
| 1470 | applyThemeColor(); | 1363 | applyThemeColor(); |
| @@ -1474,7 +1367,7 @@ applyBlurStrength(); | |||
| 1474 | applyShadowWidth(); | 1367 | applyShadowWidth(); |
| 1475 | applyCustomCSS(); | 1368 | applyCustomCSS(); |
| 1476 | switchMovingUI(); | 1369 | switchMovingUI(); |
| 1477 | noShadows(); | 1370 | applyNoShadows(); |
| 1478 | switchHotswap(); | 1371 | switchHotswap(); |
| 1479 | switchTimer(); | 1372 | switchTimer(); |
| 1480 | switchTimestamps(); | 1373 | switchTimestamps(); |
| @@ -1483,6 +1376,7 @@ switchMesIDDisplay(); | |||
| 1483 | switchHideChatAvatars(); | 1376 | switchHideChatAvatars(); |
| 1484 | switchTokenCount(); | 1377 | switchTokenCount(); |
| 1485 | switchMessageActions(); | 1378 | switchMessageActions(); |
| 1379 | } | ||
| 1486 | 1380 | ||
| 1487 | function getExampleMessagesBehavior() { | 1381 | function getExampleMessagesBehavior() { |
| 1488 | if (power_user.strip_examples) { | 1382 | if (power_user.strip_examples) { |
| @@ -1545,20 +1439,10 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1545 | context_presets = data.context; | 1439 | context_presets = data.context; |
| 1546 | } | 1440 | } |
| 1547 | 1441 | ||
| 1548 | // These are still local storage | 1442 | // These are still local storage. Delete in 1.12.7 |
| 1549 | const fastUi = localStorage.getItem(storage_keys.fast_ui_mode); | ||
| 1550 | const movingUI = localStorage.getItem(storage_keys.movingUI); | ||
| 1551 | const noShadows = localStorage.getItem(storage_keys.noShadows); | ||
| 1552 | const hotswap = localStorage.getItem(storage_keys.hotswap_enabled); | ||
| 1553 | const timer = localStorage.getItem(storage_keys.timer_enabled); | ||
| 1554 | const timestamps = localStorage.getItem(storage_keys.timestamps_enabled); | ||
| 1555 | const mesIDDisplay = localStorage.getItem(storage_keys.mesIDDisplay_enabled); | ||
| 1556 | const hideChatAvatars = localStorage.getItem(storage_keys.hideChatAvatars_enabled); | ||
| 1557 | const expandMessageActions = localStorage.getItem(storage_keys.expand_message_actions); | ||
| 1558 | const enableZenSliders = localStorage.getItem(storage_keys.enableZenSliders); | ||
| 1559 | const enableLabMode = localStorage.getItem(storage_keys.enableLabMode); | ||
| 1560 | const autoLoadChat = localStorage.getItem(storage_keys.auto_load_chat_legacy); | 1443 | const autoLoadChat = localStorage.getItem(storage_keys.auto_load_chat_legacy); |
| 1561 | const autoConnect = localStorage.getItem(storage_keys.auto_connect_legacy); | 1444 | const autoConnect = localStorage.getItem(storage_keys.auto_connect_legacy); |
| 1445 | const hideChatAvatars = localStorage.getItem(storage_keys.hideChatAvatars_legacy); | ||
| 1562 | 1446 | ||
| 1563 | if (autoLoadChat) { | 1447 | if (autoLoadChat) { |
| 1564 | power_user.auto_load_chat = autoLoadChat === 'true'; | 1448 | power_user.auto_load_chat = autoLoadChat === 'true'; |
| @@ -1570,22 +1454,10 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1570 | localStorage.removeItem(storage_keys.auto_connect_legacy); | 1454 | localStorage.removeItem(storage_keys.auto_connect_legacy); |
| 1571 | } | 1455 | } |
| 1572 | 1456 | ||
| 1573 | power_user.fast_ui_mode = fastUi === null ? true : fastUi == 'true'; | 1457 | if (hideChatAvatars) { |
| 1574 | power_user.movingUI = movingUI === null ? false : movingUI == 'true'; | 1458 | power_user.hideChatAvatars_enabled = hideChatAvatars === 'true'; |
| 1575 | power_user.noShadows = noShadows === null ? false : noShadows == 'true'; | 1459 | localStorage.removeItem(storage_keys.hideChatAvatars_legacy); |
| 1576 | power_user.hotswap_enabled = hotswap === null ? true : hotswap == 'true'; | 1460 | } |
| 1577 | power_user.timer_enabled = timer === null ? true : timer == 'true'; | ||
| 1578 | power_user.timestamps_enabled = timestamps === null ? true : timestamps == 'true'; | ||
| 1579 | power_user.mesIDDisplay_enabled = mesIDDisplay === null ? true : mesIDDisplay == 'true'; | ||
| 1580 | power_user.hideChatAvatars_enabled = hideChatAvatars === null ? true : hideChatAvatars == 'true'; | ||
| 1581 | power_user.expand_message_actions = expandMessageActions === null ? true : expandMessageActions == 'true'; | ||
| 1582 | power_user.enableZenSliders = enableZenSliders === null ? false : enableZenSliders == 'true'; | ||
| 1583 | power_user.enableLabMode = enableLabMode === null ? false : enableLabMode == 'true'; | ||
| 1584 | power_user.avatar_style = Number(localStorage.getItem(storage_keys.avatar_style) ?? avatar_styles.ROUND); | ||
| 1585 | //power_user.chat_display = Number(localStorage.getItem(storage_keys.chat_display) ?? chat_styles.DEFAULT); | ||
| 1586 | power_user.chat_width = Number(localStorage.getItem(storage_keys.chat_width) ?? 50); | ||
| 1587 | power_user.font_scale = Number(localStorage.getItem(storage_keys.font_scale) ?? 1); | ||
| 1588 | power_user.blur_strength = Number(localStorage.getItem(storage_keys.blur_strength) ?? 10); | ||
| 1589 | 1461 | ||
| 1590 | if (power_user.chat_display === '') { | 1462 | if (power_user.chat_display === '') { |
| 1591 | power_user.chat_display = chat_styles.DEFAULT; | 1463 | power_user.chat_display = chat_styles.DEFAULT; |
| @@ -1672,7 +1544,7 @@ async function loadPowerUserSettings(settings, data) { | |||
| 1672 | $('#messageTimestampsEnabled').prop('checked', power_user.timestamps_enabled); | 1544 | $('#messageTimestampsEnabled').prop('checked', power_user.timestamps_enabled); |
| 1673 | $('#messageModelIconEnabled').prop('checked', power_user.timestamp_model_icon); | 1545 | $('#messageModelIconEnabled').prop('checked', power_user.timestamp_model_icon); |
| 1674 | $('#mesIDDisplayEnabled').prop('checked', power_user.mesIDDisplay_enabled); | 1546 | $('#mesIDDisplayEnabled').prop('checked', power_user.mesIDDisplay_enabled); |
| 1675 | $('#hideChatAvatarsEndabled').prop('checked', power_user.hideChatAvatars_enabled); | 1547 | $('#hideChatAvatarsEnabled').prop('checked', power_user.hideChatAvatars_enabled); |
| 1676 | $('#prefer_character_prompt').prop('checked', power_user.prefer_character_prompt); | 1548 | $('#prefer_character_prompt').prop('checked', power_user.prefer_character_prompt); |
| 1677 | $('#prefer_character_jailbreak').prop('checked', power_user.prefer_character_jailbreak); | 1549 | $('#prefer_character_jailbreak').prop('checked', power_user.prefer_character_jailbreak); |
| 1678 | $('#enableZenSliders').prop('checked', power_user.enableZenSliders).trigger('input'); | 1550 | $('#enableZenSliders').prop('checked', power_user.enableZenSliders).trigger('input'); |
| @@ -3313,10 +3185,8 @@ $(document).ready(() => { | |||
| 3313 | saveSettingsDebounced(); | 3185 | saveSettingsDebounced(); |
| 3314 | }); | 3186 | }); |
| 3315 | 3187 | ||
| 3316 | // Settings that go to local storage | ||
| 3317 | $('#fast_ui_mode').change(function () { | 3188 | $('#fast_ui_mode').change(function () { |
| 3318 | power_user.fast_ui_mode = $(this).prop('checked'); | 3189 | power_user.fast_ui_mode = $(this).prop('checked'); |
| 3319 | localStorage.setItem(storage_keys.fast_ui_mode, power_user.fast_ui_mode); | ||
| 3320 | switchUiMode(); | 3190 | switchUiMode(); |
| 3321 | saveSettingsDebounced(); | 3191 | saveSettingsDebounced(); |
| 3322 | }); | 3192 | }); |
| @@ -3329,22 +3199,19 @@ $(document).ready(() => { | |||
| 3329 | 3199 | ||
| 3330 | $('#customCSS').on('input', () => { | 3200 | $('#customCSS').on('input', () => { |
| 3331 | power_user.custom_css = String($('#customCSS').val()); | 3201 | power_user.custom_css = String($('#customCSS').val()); |
| 3332 | localStorage.setItem(storage_keys.custom_css, power_user.custom_css); | ||
| 3333 | saveSettingsDebounced(); | 3202 | saveSettingsDebounced(); |
| 3334 | applyCustomCSS(); | 3203 | applyCustomCSS(); |
| 3335 | }); | 3204 | }); |
| 3336 | 3205 | ||
| 3337 | $('#movingUImode').change(function () { | 3206 | $('#movingUImode').change(function () { |
| 3338 | power_user.movingUI = $(this).prop('checked'); | 3207 | power_user.movingUI = $(this).prop('checked'); |
| 3339 | localStorage.setItem(storage_keys.movingUI, power_user.movingUI); | ||
| 3340 | switchMovingUI(); | 3208 | switchMovingUI(); |
| 3341 | saveSettingsDebounced(); | 3209 | saveSettingsDebounced(); |
| 3342 | }); | 3210 | }); |
| 3343 | 3211 | ||
| 3344 | $('#noShadowsmode').change(function () { | 3212 | $('#noShadowsmode').change(function () { |
| 3345 | power_user.noShadows = $(this).prop('checked'); | 3213 | power_user.noShadows = $(this).prop('checked'); |
| 3346 | localStorage.setItem(storage_keys.noShadows, power_user.noShadows); | 3214 | applyNoShadows(); |
| 3347 | noShadows(); | ||
| 3348 | saveSettingsDebounced(); | 3215 | saveSettingsDebounced(); |
| 3349 | }); | 3216 | }); |
| 3350 | 3217 | ||
| @@ -3353,7 +3220,6 @@ $(document).ready(() => { | |||
| 3353 | $('#avatar_style').on('change', function () { | 3220 | $('#avatar_style').on('change', function () { |
| 3354 | const value = $(this).find(':selected').val(); | 3221 | const value = $(this).find(':selected').val(); |
| 3355 | power_user.avatar_style = Number(value); | 3222 | power_user.avatar_style = Number(value); |
| 3356 | localStorage.setItem(storage_keys.avatar_style, power_user.avatar_style); | ||
| 3357 | applyAvatarStyle(); | 3223 | applyAvatarStyle(); |
| 3358 | saveSettingsDebounced(); | 3224 | saveSettingsDebounced(); |
| 3359 | }); | 3225 | }); |
| @@ -3361,17 +3227,15 @@ $(document).ready(() => { | |||
| 3361 | $('#chat_display').on('change', function () { | 3227 | $('#chat_display').on('change', function () { |
| 3362 | const value = $(this).find(':selected').val(); | 3228 | const value = $(this).find(':selected').val(); |
| 3363 | power_user.chat_display = Number(value); | 3229 | power_user.chat_display = Number(value); |
| 3364 | localStorage.setItem(storage_keys.chat_display, power_user.chat_display); | ||
| 3365 | applyChatDisplay(); | 3230 | applyChatDisplay(); |
| 3366 | saveSettingsDebounced(); | 3231 | saveSettingsDebounced(); |
| 3367 | |||
| 3368 | }); | 3232 | }); |
| 3369 | 3233 | ||
| 3370 | $('#chat_width_slider').on('input', function (e, data) { | 3234 | $('#chat_width_slider').on('input', function (e, data) { |
| 3371 | const applyMode = data?.forced ? 'forced' : 'normal'; | 3235 | const applyMode = data?.forced ? 'forced' : 'normal'; |
| 3372 | power_user.chat_width = Number(e.target.value); | 3236 | power_user.chat_width = Number(e.target.value); |
| 3373 | localStorage.setItem(storage_keys.chat_width, power_user.chat_width); | ||
| 3374 | applyChatWidth(applyMode); | 3237 | applyChatWidth(applyMode); |
| 3238 | saveSettingsDebounced(); | ||
| 3375 | setHotswapsDebounced(); | 3239 | setHotswapsDebounced(); |
| 3376 | }); | 3240 | }); |
| 3377 | 3241 | ||
| @@ -3401,7 +3265,6 @@ $(document).ready(() => { | |||
| 3401 | const applyMode = data?.forced ? 'forced' : 'normal'; | 3265 | const applyMode = data?.forced ? 'forced' : 'normal'; |
| 3402 | power_user.font_scale = Number(e.target.value); | 3266 | power_user.font_scale = Number(e.target.value); |
| 3403 | $('#font_scale_counter').val(power_user.font_scale); | 3267 | $('#font_scale_counter').val(power_user.font_scale); |
| 3404 | localStorage.setItem(storage_keys.font_scale, power_user.font_scale); | ||
| 3405 | await applyFontScale(applyMode); | 3268 | await applyFontScale(applyMode); |
| 3406 | saveSettingsDebounced(); | 3269 | saveSettingsDebounced(); |
| 3407 | }); | 3270 | }); |
| @@ -3409,7 +3272,6 @@ $(document).ready(() => { | |||
| 3409 | $('input[name="blur_strength"]').on('input', async function (e) { | 3272 | $('input[name="blur_strength"]').on('input', async function (e) { |
| 3410 | power_user.blur_strength = Number(e.target.value); | 3273 | power_user.blur_strength = Number(e.target.value); |
| 3411 | $('#blur_strength_counter').val(power_user.blur_strength); | 3274 | $('#blur_strength_counter').val(power_user.blur_strength); |
| 3412 | localStorage.setItem(storage_keys.blur_strength, power_user.blur_strength); | ||
| 3413 | await applyBlurStrength(); | 3275 | await applyBlurStrength(); |
| 3414 | saveSettingsDebounced(); | 3276 | saveSettingsDebounced(); |
| 3415 | }); | 3277 | }); |
| @@ -3417,7 +3279,6 @@ $(document).ready(() => { | |||
| 3417 | $('input[name="shadow_width"]').on('input', async function (e) { | 3279 | $('input[name="shadow_width"]').on('input', async function (e) { |
| 3418 | power_user.shadow_width = Number(e.target.value); | 3280 | power_user.shadow_width = Number(e.target.value); |
| 3419 | $('#shadow_width_counter').val(power_user.shadow_width); | 3281 | $('#shadow_width_counter').val(power_user.shadow_width); |
| 3420 | localStorage.setItem(storage_keys.shadow_width, power_user.shadow_width); | ||
| 3421 | await applyShadowWidth(); | 3282 | await applyShadowWidth(); |
| 3422 | saveSettingsDebounced(); | 3283 | saveSettingsDebounced(); |
| 3423 | }); | 3284 | }); |
| @@ -3658,36 +3519,36 @@ $(document).ready(() => { | |||
| 3658 | $('#messageTimerEnabled').on('input', function () { | 3519 | $('#messageTimerEnabled').on('input', function () { |
| 3659 | const value = !!$(this).prop('checked'); | 3520 | const value = !!$(this).prop('checked'); |
| 3660 | power_user.timer_enabled = value; | 3521 | power_user.timer_enabled = value; |
| 3661 | localStorage.setItem(storage_keys.timer_enabled, Boolean(power_user.timer_enabled)); | ||
| 3662 | switchTimer(); | 3522 | switchTimer(); |
| 3523 | saveSettingsDebounced(); | ||
| 3663 | }); | 3524 | }); |
| 3664 | 3525 | ||
| 3665 | $('#messageTimestampsEnabled').on('input', function () { | 3526 | $('#messageTimestampsEnabled').on('input', function () { |
| 3666 | const value = !!$(this).prop('checked'); | 3527 | const value = !!$(this).prop('checked'); |
| 3667 | power_user.timestamps_enabled = value; | 3528 | power_user.timestamps_enabled = value; |
| 3668 | localStorage.setItem(storage_keys.timestamps_enabled, Boolean(power_user.timestamps_enabled)); | ||
| 3669 | switchTimestamps(); | 3529 | switchTimestamps(); |
| 3530 | saveSettingsDebounced(); | ||
| 3670 | }); | 3531 | }); |
| 3671 | 3532 | ||
| 3672 | $('#messageModelIconEnabled').on('input', function () { | 3533 | $('#messageModelIconEnabled').on('input', function () { |
| 3673 | const value = !!$(this).prop('checked'); | 3534 | const value = !!$(this).prop('checked'); |
| 3674 | power_user.timestamp_model_icon = value; | 3535 | power_user.timestamp_model_icon = value; |
| 3675 | localStorage.setItem(storage_keys.timestamp_model_icon, Boolean(power_user.timestamp_model_icon)); | ||
| 3676 | switchIcons(); | 3536 | switchIcons(); |
| 3537 | saveSettingsDebounced(); | ||
| 3677 | }); | 3538 | }); |
| 3678 | 3539 | ||
| 3679 | $('#messageTokensEnabled').on('input', function () { | 3540 | $('#messageTokensEnabled').on('input', function () { |
| 3680 | const value = !!$(this).prop('checked'); | 3541 | const value = !!$(this).prop('checked'); |
| 3681 | power_user.message_token_count_enabled = value; | 3542 | power_user.message_token_count_enabled = value; |
| 3682 | localStorage.setItem(storage_keys.message_token_count_enabled, Boolean(power_user.message_token_count_enabled)); | ||
| 3683 | switchTokenCount(); | 3543 | switchTokenCount(); |
| 3544 | saveSettingsDebounced(); | ||
| 3684 | }); | 3545 | }); |
| 3685 | 3546 | ||
| 3686 | $('#expandMessageActions').on('input', function () { | 3547 | $('#expandMessageActions').on('input', function () { |
| 3687 | const value = !!$(this).prop('checked'); | 3548 | const value = !!$(this).prop('checked'); |
| 3688 | power_user.expand_message_actions = value; | 3549 | power_user.expand_message_actions = value; |
| 3689 | localStorage.setItem(storage_keys.expand_message_actions, Boolean(power_user.expand_message_actions)); | ||
| 3690 | switchMessageActions(); | 3550 | switchMessageActions(); |
| 3551 | saveSettingsDebounced(); | ||
| 3691 | }); | 3552 | }); |
| 3692 | 3553 | ||
| 3693 | $('#enableZenSliders').on('input', function () { | 3554 | $('#enableZenSliders').on('input', function () { |
| @@ -3699,9 +3560,8 @@ $(document).ready(() => { | |||
| 3699 | return; | 3560 | return; |
| 3700 | } | 3561 | } |
| 3701 | power_user.enableZenSliders = value; | 3562 | power_user.enableZenSliders = value; |
| 3702 | localStorage.setItem(storage_keys.enableZenSliders, Boolean(power_user.enableZenSliders)); | ||
| 3703 | saveSettingsDebounced(); | ||
| 3704 | switchZenSliders(); | 3563 | switchZenSliders(); |
| 3564 | saveSettingsDebounced(); | ||
| 3705 | }); | 3565 | }); |
| 3706 | 3566 | ||
| 3707 | $('#enableLabMode').on('input', function () { | 3567 | $('#enableLabMode').on('input', function () { |
| @@ -3714,30 +3574,29 @@ $(document).ready(() => { | |||
| 3714 | } | 3574 | } |
| 3715 | 3575 | ||
| 3716 | power_user.enableLabMode = value; | 3576 | power_user.enableLabMode = value; |
| 3717 | localStorage.setItem(storage_keys.enableLabMode, Boolean(power_user.enableLabMode)); | ||
| 3718 | saveSettingsDebounced(); | ||
| 3719 | switchLabMode(); | 3577 | switchLabMode(); |
| 3578 | saveSettingsDebounced(); | ||
| 3720 | }); | 3579 | }); |
| 3721 | 3580 | ||
| 3722 | $('#mesIDDisplayEnabled').on('input', function () { | 3581 | $('#mesIDDisplayEnabled').on('input', function () { |
| 3723 | const value = !!$(this).prop('checked'); | 3582 | const value = !!$(this).prop('checked'); |
| 3724 | power_user.mesIDDisplay_enabled = value; | 3583 | power_user.mesIDDisplay_enabled = value; |
| 3725 | localStorage.setItem(storage_keys.mesIDDisplay_enabled, Boolean(power_user.mesIDDisplay_enabled)); | ||
| 3726 | switchMesIDDisplay(); | 3584 | switchMesIDDisplay(); |
| 3585 | saveSettingsDebounced(); | ||
| 3727 | }); | 3586 | }); |
| 3728 | 3587 | ||
| 3729 | $('#hideChatAvatarsEnabled').on('input', function () { | 3588 | $('#hideChatAvatarsEnabled').on('input', function () { |
| 3730 | const value = !!$(this).prop('checked'); | 3589 | const value = !!$(this).prop('checked'); |
| 3731 | power_user.hideChatAvatars_enabled = value; | 3590 | power_user.hideChatAvatars_enabled = value; |
| 3732 | localStorage.setItem(storage_keys.hideChatAvatars_enabled, Boolean(power_user.hideChatAvatars_enabled)); | ||
| 3733 | switchHideChatAvatars(); | 3591 | switchHideChatAvatars(); |
| 3592 | saveSettingsDebounced(); | ||
| 3734 | }); | 3593 | }); |
| 3735 | 3594 | ||
| 3736 | $('#hotswapEnabled').on('input', function () { | 3595 | $('#hotswapEnabled').on('input', function () { |
| 3737 | const value = !!$(this).prop('checked'); | 3596 | const value = !!$(this).prop('checked'); |
| 3738 | power_user.hotswap_enabled = value; | 3597 | power_user.hotswap_enabled = value; |
| 3739 | localStorage.setItem(storage_keys.hotswap_enabled, Boolean(power_user.hotswap_enabled)); | ||
| 3740 | switchHotswap(); | 3598 | switchHotswap(); |
| 3599 | saveSettingsDebounced(); | ||
| 3741 | }); | 3600 | }); |
| 3742 | 3601 | ||
| 3743 | $('#prefer_character_prompt').on('input', function () { | 3602 | $('#prefer_character_prompt').on('input', function () { |
| @@ -3845,8 +3704,8 @@ $(document).ready(() => { | |||
| 3845 | $('#ui_mode_select').on('change', function () { | 3704 | $('#ui_mode_select').on('change', function () { |
| 3846 | const value = $(this).find(':selected').val(); | 3705 | const value = $(this).find(':selected').val(); |
| 3847 | power_user.ui_mode = Number(value); | 3706 | power_user.ui_mode = Number(value); |
| 3848 | saveSettingsDebounced(); | ||
| 3849 | switchSimpleMode(); | 3707 | switchSimpleMode(); |
| 3708 | saveSettingsDebounced(); | ||
| 3850 | }); | 3709 | }); |
| 3851 | 3710 | ||
| 3852 | $('#bogus_folders').on('input', function () { | 3711 | $('#bogus_folders').on('input', function () { |
| @@ -3950,14 +3809,12 @@ $(document).ready(() => { | |||
| 3950 | 3809 | ||
| 3951 | $('#reduced_motion').on('input', function () { | 3810 | $('#reduced_motion').on('input', function () { |
| 3952 | power_user.reduced_motion = !!$(this).prop('checked'); | 3811 | power_user.reduced_motion = !!$(this).prop('checked'); |
| 3953 | localStorage.setItem(storage_keys.reduced_motion, String(power_user.reduced_motion)); | ||
| 3954 | switchReducedMotion(); | 3812 | switchReducedMotion(); |
| 3955 | saveSettingsDebounced(); | 3813 | saveSettingsDebounced(); |
| 3956 | }); | 3814 | }); |
| 3957 | 3815 | ||
| 3958 | $('#compact_input_area').on('input', function () { | 3816 | $('#compact_input_area').on('input', function () { |
| 3959 | power_user.compact_input_area = !!$(this).prop('checked'); | 3817 | power_user.compact_input_area = !!$(this).prop('checked'); |
| 3960 | localStorage.setItem(storage_keys.compact_input_area, String(power_user.compact_input_area)); | ||
| 3961 | switchCompactInputArea(); | 3818 | switchCompactInputArea(); |
| 3962 | saveSettingsDebounced(); | 3819 | saveSettingsDebounced(); |
| 3963 | }); | 3820 | }); |
| @@ -8,7 +8,7 @@ export const markdownUnderscoreExt = () => { | |||
| 8 | 8 | ||
| 9 | return [{ | 9 | return [{ |
| 10 | type: 'output', | 10 | type: 'output', |
| 11 | regex: new RegExp('(<code>[\\s\\S]*?<\\/code>)|(?<!\\S)_(?!_)([^_\\n]+?)(?<!_)_(?!\\w)', 'g'), | 11 | regex: new RegExp('(<code(?:\\s+[^>]*)?>[\\s\\S]*?<\\/code>)|\\b(?<!_)_(?!_)(.*?)(?<!_)_(?!_)\\b', 'g'), |
| 12 | replace: function(match, codeContent, italicContent) { | 12 | replace: function(match, codeContent, italicContent) { |
| 13 | if (codeContent) { | 13 | if (codeContent) { |
| 14 | // If it's inside <code> tags, return unchanged | 14 | // If it's inside <code> tags, return unchanged |
| @@ -2147,12 +2147,13 @@ async function generateRawCallback(args, value) { | |||
| 2147 | } | 2147 | } |
| 2148 | } | 2148 | } |
| 2149 | 2149 | ||
| 2150 | /** | ||
| 2151 | * Callback for the /gen command | ||
| 2152 | * @param {object} args Named arguments | ||
| 2153 | * @param {string} value Unnamed argument | ||
| 2154 | * @returns {Promise<string>} The generated text | ||
| 2155 | */ | ||
| 2150 | async function generateCallback(args, value) { | 2156 | async function generateCallback(args, value) { |
| 2151 | if (!value) { | ||
| 2152 | console.warn('WARN: No argument provided for /gen command'); | ||
| 2153 | return; | ||
| 2154 | } | ||
| 2155 | |||
| 2156 | // Prevent generate recursion | 2157 | // Prevent generate recursion |
| 2157 | $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true })); | 2158 | $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true })); |
| 2158 | const lock = isTrueBoolean(args?.lock); | 2159 | const lock = isTrueBoolean(args?.lock); |
| @@ -445,7 +445,11 @@ export function getTagKeyForEntity(entityOrKey) { | |||
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | // Next lets check if its a valid character or character id, so we can swith it to its tag | 447 | // Next lets check if its a valid character or character id, so we can swith it to its tag |
| 448 | const character = characters.indexOf(x) >= 0 ? x : characters[x]; | 448 | let character; |
| 449 | if (!character && characters.indexOf(x) >= 0) character = x; // Check for char object | ||
| 450 | if (!character && !isNaN(parseInt(entityOrKey))) character = characters[x]; // check if its a char id | ||
| 451 | if (!character) character = characters.find(y => y.avatar === x); // check if its a char key | ||
| 452 | |||
| 449 | if (character) { | 453 | if (character) { |
| 450 | x = character.avatar; | 454 | x = character.avatar; |
| 451 | } | 455 | } |
| @@ -722,7 +726,11 @@ async function importTags(character, { importSetting = null } = {}) { | |||
| 722 | const tagsToImport = tagNamesToImport.map(tag => getTag(tag, { createNew: true })); | 726 | const tagsToImport = tagNamesToImport.map(tag => getTag(tag, { createNew: true })); |
| 723 | const added = addTagsToEntity(tagsToImport, character.avatar); | 727 | const added = addTagsToEntity(tagsToImport, character.avatar); |
| 724 | 728 | ||
| 729 | if (added) { | ||
| 725 | toastr.success(`Imported tags:<br />${tagsToImport.map(x => x.name).join(', ')}`, 'Importing Tags', { escapeHtml: false }); | 730 | toastr.success(`Imported tags:<br />${tagsToImport.map(x => x.name).join(', ')}`, 'Importing Tags', { escapeHtml: false }); |
| 731 | } else { | ||
| 732 | toastr.error(`Couldn't import tags:<br />${tagsToImport.map(x => x.name).join(', ')}`, 'Importing Tags', { escapeHtml: false }); | ||
| 733 | } | ||
| 726 | 734 | ||
| 727 | return added; | 735 | return added; |
| 728 | } | 736 | } |
| @@ -0,0 +1,6 @@ | |||
| 1 | <h3 data-i18n="chat_rename_1">Enter the new name for the chat:</h3> | ||
| 2 | <small> | ||
| 3 | <span data-i18n="chat_rename_2">!!Using an existing filename will produce an error!!</span><br> | ||
| 4 | <span data-i18n="chat_rename_3">This will break the link between checkpoint chats.</span><br> | ||
| 5 | <span data-i18n="chat_rename_4">No need to add '.jsonl' at the end.</span><br> | ||
| 6 | </small> | ||
| \ No newline at end of file | 6 | \ No newline at end of file | |
| @@ -0,0 +1,4 @@ | |||
| 1 | <label for="del_chat_checkbox" class="checkbox_label justifyCenter" data-i18n="[title]If necessary, you can later restore this chat file from the /backups folder" title="If necessary, you can later restore this chat file from the /backups folder"> | ||
| 2 | <input type="checkbox" id="del_chat_checkbox" /> | ||
| 3 | <small data-i18n="Also delete the current chat file">Also delete the current chat file</small> | ||
| 4 | </label> | ||
| \ No newline at end of file | 4 | \ No newline at end of file | |
| @@ -0,0 +1 @@ | |||
| 1 | <span data-i18n="Are you sure you want to connect to the following proxy URL?">Are you sure you want to connect to the following proxy URL?</span><var>{{proxyURL}}</var> | ||
| \ No newline at end of file | 1 | \ No newline at end of file | |
| @@ -27,6 +27,7 @@ export const tokenizers = { | |||
| 27 | CLAUDE: 11, | 27 | CLAUDE: 11, |
| 28 | LLAMA3: 12, | 28 | LLAMA3: 12, |
| 29 | GEMMA: 13, | 29 | GEMMA: 13, |
| 30 | JAMBA: 14, | ||
| 30 | BEST_MATCH: 99, | 31 | BEST_MATCH: 99, |
| 31 | }; | 32 | }; |
| 32 | 33 | ||
| @@ -36,6 +37,7 @@ export const SENTENCEPIECE_TOKENIZERS = [ | |||
| 36 | tokenizers.YI, | 37 | tokenizers.YI, |
| 37 | tokenizers.LLAMA3, | 38 | tokenizers.LLAMA3, |
| 38 | tokenizers.GEMMA, | 39 | tokenizers.GEMMA, |
| 40 | tokenizers.JAMBA, | ||
| 39 | // uncomment when NovelAI releases Kayra and Clio weights, lol | 41 | // uncomment when NovelAI releases Kayra and Clio weights, lol |
| 40 | //tokenizers.NERD, | 42 | //tokenizers.NERD, |
| 41 | //tokenizers.NERD2, | 43 | //tokenizers.NERD2, |
| @@ -98,6 +100,11 @@ const TOKENIZER_URLS = { | |||
| 98 | decode: '/api/tokenizers/gemma/decode', | 100 | decode: '/api/tokenizers/gemma/decode', |
| 99 | count: '/api/tokenizers/gemma/encode', | 101 | count: '/api/tokenizers/gemma/encode', |
| 100 | }, | 102 | }, |
| 103 | [tokenizers.JAMBA]: { | ||
| 104 | encode: '/api/tokenizers/jamba/encode', | ||
| 105 | decode: '/api/tokenizers/jamba/decode', | ||
| 106 | count: '/api/tokenizers/jamba/encode', | ||
| 107 | }, | ||
| 101 | [tokenizers.API_TEXTGENERATIONWEBUI]: { | 108 | [tokenizers.API_TEXTGENERATIONWEBUI]: { |
| 102 | encode: '/api/tokenizers/remote/textgenerationwebui/encode', | 109 | encode: '/api/tokenizers/remote/textgenerationwebui/encode', |
| 103 | count: '/api/tokenizers/remote/textgenerationwebui/encode', | 110 | count: '/api/tokenizers/remote/textgenerationwebui/encode', |
| @@ -164,7 +171,7 @@ export function getAvailableTokenizers() { | |||
| 164 | tokenizerId: Number(tokenizerOption.value), | 171 | tokenizerId: Number(tokenizerOption.value), |
| 165 | tokenizerKey: Object.entries(tokenizers).find(([_, value]) => value === Number(tokenizerOption.value))[0].toLocaleLowerCase(), | 172 | tokenizerKey: Object.entries(tokenizers).find(([_, value]) => value === Number(tokenizerOption.value))[0].toLocaleLowerCase(), |
| 166 | tokenizerName: tokenizerOption.text, | 173 | tokenizerName: tokenizerOption.text, |
| 167 | })) | 174 | })); |
| 168 | } | 175 | } |
| 169 | 176 | ||
| 170 | /** | 177 | /** |
| @@ -280,6 +287,12 @@ export function getTokenizerBestMatch(forApi) { | |||
| 280 | if (model.includes('gemma')) { | 287 | if (model.includes('gemma')) { |
| 281 | return tokenizers.GEMMA; | 288 | return tokenizers.GEMMA; |
| 282 | } | 289 | } |
| 290 | if (model.includes('yi')) { | ||
| 291 | return tokenizers.YI; | ||
| 292 | } | ||
| 293 | if (model.includes('jamba')) { | ||
| 294 | return tokenizers.JAMBA; | ||
| 295 | } | ||
| 283 | } | 296 | } |
| 284 | 297 | ||
| 285 | return tokenizers.LLAMA; | 298 | return tokenizers.LLAMA; |
| @@ -497,6 +510,7 @@ export function getTokenizerModel() { | |||
| 497 | const mistralTokenizer = 'mistral'; | 510 | const mistralTokenizer = 'mistral'; |
| 498 | const yiTokenizer = 'yi'; | 511 | const yiTokenizer = 'yi'; |
| 499 | const gemmaTokenizer = 'gemma'; | 512 | const gemmaTokenizer = 'gemma'; |
| 513 | const jambaTokenizer = 'jamba'; | ||
| 500 | 514 | ||
| 501 | // Assuming no one would use it for different models.. right? | 515 | // Assuming no one would use it for different models.. right? |
| 502 | if (oai_settings.chat_completion_source == chat_completion_sources.SCALE) { | 516 | if (oai_settings.chat_completion_source == chat_completion_sources.SCALE) { |
| @@ -562,12 +576,19 @@ export function getTokenizerModel() { | |||
| 562 | else if (oai_settings.openrouter_model.includes('GPT-NeoXT')) { | 576 | else if (oai_settings.openrouter_model.includes('GPT-NeoXT')) { |
| 563 | return gpt2Tokenizer; | 577 | return gpt2Tokenizer; |
| 564 | } | 578 | } |
| 579 | else if (oai_settings.openrouter_model.includes('jamba')) { | ||
| 580 | return jambaTokenizer; | ||
| 581 | } | ||
| 565 | } | 582 | } |
| 566 | 583 | ||
| 567 | if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { | 584 | if (oai_settings.chat_completion_source == chat_completion_sources.MAKERSUITE) { |
| 568 | return gemmaTokenizer; | 585 | return gemmaTokenizer; |
| 569 | } | 586 | } |
| 570 | 587 | ||
| 588 | if (oai_settings.chat_completion_source == chat_completion_sources.AI21) { | ||
| 589 | return jambaTokenizer; | ||
| 590 | } | ||
| 591 | |||
| 571 | if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) { | 592 | if (oai_settings.chat_completion_source == chat_completion_sources.CLAUDE) { |
| 572 | return claudeTokenizer; | 593 | return claudeTokenizer; |
| 573 | } | 594 | } |
| @@ -626,16 +647,7 @@ export function getTokenizerModel() { | |||
| 626 | * @deprecated Use countTokensOpenAIAsync instead. | 647 | * @deprecated Use countTokensOpenAIAsync instead. |
| 627 | */ | 648 | */ |
| 628 | export function countTokensOpenAI(messages, full = false) { | 649 | export function countTokensOpenAI(messages, full = false) { |
| 629 | const shouldTokenizeAI21 = oai_settings.chat_completion_source === chat_completion_sources.AI21 && oai_settings.use_ai21_tokenizer; | 650 | const tokenizerEndpoint = `/api/tokenizers/openai/count?model=${getTokenizerModel()}`; |
| 630 | const shouldTokenizeGoogle = oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE && oai_settings.use_google_tokenizer; | ||
| 631 | let tokenizerEndpoint = ''; | ||
| 632 | if (shouldTokenizeAI21) { | ||
| 633 | tokenizerEndpoint = '/api/tokenizers/ai21/count'; | ||
| 634 | } else if (shouldTokenizeGoogle) { | ||
| 635 | tokenizerEndpoint = `/api/tokenizers/google/count?model=${getTokenizerModel()}&reverse_proxy=${oai_settings.reverse_proxy}&proxy_password=${oai_settings.proxy_password}`; | ||
| 636 | } else { | ||
| 637 | tokenizerEndpoint = `/api/tokenizers/openai/count?model=${getTokenizerModel()}`; | ||
| 638 | } | ||
| 639 | const cacheObject = getTokenCacheObject(); | 651 | const cacheObject = getTokenCacheObject(); |
| 640 | 652 | ||
| 641 | if (!Array.isArray(messages)) { | 653 | if (!Array.isArray(messages)) { |
| @@ -647,7 +659,7 @@ export function countTokensOpenAI(messages, full = false) { | |||
| 647 | for (const message of messages) { | 659 | for (const message of messages) { |
| 648 | const model = getTokenizerModel(); | 660 | const model = getTokenizerModel(); |
| 649 | 661 | ||
| 650 | if (model === 'claude' || shouldTokenizeAI21 || shouldTokenizeGoogle) { | 662 | if (model === 'claude') { |
| 651 | full = true; | 663 | full = true; |
| 652 | } | 664 | } |
| 653 | 665 | ||
| @@ -687,16 +699,7 @@ export function countTokensOpenAI(messages, full = false) { | |||
| 687 | * @returns {Promise<number>} Token count. | 699 | * @returns {Promise<number>} Token count. |
| 688 | */ | 700 | */ |
| 689 | export async function countTokensOpenAIAsync(messages, full = false) { | 701 | export async function countTokensOpenAIAsync(messages, full = false) { |
| 690 | const shouldTokenizeAI21 = oai_settings.chat_completion_source === chat_completion_sources.AI21 && oai_settings.use_ai21_tokenizer; | 702 | const tokenizerEndpoint = `/api/tokenizers/openai/count?model=${getTokenizerModel()}`; |
| 691 | const shouldTokenizeGoogle = oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE && oai_settings.use_google_tokenizer; | ||
| 692 | let tokenizerEndpoint = ''; | ||
| 693 | if (shouldTokenizeAI21) { | ||
| 694 | tokenizerEndpoint = '/api/tokenizers/ai21/count'; | ||
| 695 | } else if (shouldTokenizeGoogle) { | ||
| 696 | tokenizerEndpoint = `/api/tokenizers/google/count?model=${getTokenizerModel()}`; | ||
| 697 | } else { | ||
| 698 | tokenizerEndpoint = `/api/tokenizers/openai/count?model=${getTokenizerModel()}`; | ||
| 699 | } | ||
| 700 | const cacheObject = getTokenCacheObject(); | 703 | const cacheObject = getTokenCacheObject(); |
| 701 | 704 | ||
| 702 | if (!Array.isArray(messages)) { | 705 | if (!Array.isArray(messages)) { |
| @@ -708,7 +711,7 @@ export async function countTokensOpenAIAsync(messages, full = false) { | |||
| 708 | for (const message of messages) { | 711 | for (const message of messages) { |
| 709 | const model = getTokenizerModel(); | 712 | const model = getTokenizerModel(); |
| 710 | 713 | ||
| 711 | if (model === 'claude' || shouldTokenizeAI21 || shouldTokenizeGoogle) { | 714 | if (model === 'claude') { |
| 712 | full = true; | 715 | full = true; |
| 713 | } | 716 | } |
| 714 | 717 | ||
| @@ -838,6 +841,7 @@ function getTextgenAPITokenizationParams(str) { | |||
| 838 | url: getTextGenServer(), | 841 | url: getTextGenServer(), |
| 839 | legacy_api: textgen_settings.legacy_api && (textgen_settings.type === OOBA || textgen_settings.type === APHRODITE), | 842 | legacy_api: textgen_settings.legacy_api && (textgen_settings.type === OOBA || textgen_settings.type === APHRODITE), |
| 840 | vllm_model: textgen_settings.vllm_model, | 843 | vllm_model: textgen_settings.vllm_model, |
| 844 | aphrodite_model: textgen_settings.aphrodite_model, | ||
| 841 | }; | 845 | }; |
| 842 | } | 846 | } |
| 843 | 847 | ||
| @@ -73,6 +73,7 @@ export let world_info_match_whole_words = false; | |||
| 73 | export let world_info_use_group_scoring = false; | 73 | export let world_info_use_group_scoring = false; |
| 74 | export let world_info_character_strategy = world_info_insertion_strategy.character_first; | 74 | export let world_info_character_strategy = world_info_insertion_strategy.character_first; |
| 75 | export let world_info_budget_cap = 0; | 75 | export let world_info_budget_cap = 0; |
| 76 | export let world_info_max_recursion_steps = 0; | ||
| 76 | const saveWorldDebounced = debounce(async (name, data) => await _save(name, data), debounce_timeout.relaxed); | 77 | const saveWorldDebounced = debounce(async (name, data) => await _save(name, data), debounce_timeout.relaxed); |
| 77 | const saveSettingsDebounced = debounce(() => { | 78 | const saveSettingsDebounced = debounce(() => { |
| 78 | Object.assign(world_info, { globalSelect: selected_world_info }); | 79 | Object.assign(world_info, { globalSelect: selected_world_info }); |
| @@ -710,6 +711,7 @@ export function getWorldInfoSettings() { | |||
| 710 | world_info_character_strategy, | 711 | world_info_character_strategy, |
| 711 | world_info_budget_cap, | 712 | world_info_budget_cap, |
| 712 | world_info_use_group_scoring, | 713 | world_info_use_group_scoring, |
| 714 | world_info_max_recursion_steps, | ||
| 713 | }; | 715 | }; |
| 714 | } | 716 | } |
| 715 | 717 | ||
| @@ -796,6 +798,8 @@ export function setWorldInfoSettings(settings, data) { | |||
| 796 | world_info_budget_cap = Number(settings.world_info_budget_cap); | 798 | world_info_budget_cap = Number(settings.world_info_budget_cap); |
| 797 | if (settings.world_info_use_group_scoring !== undefined) | 799 | if (settings.world_info_use_group_scoring !== undefined) |
| 798 | world_info_use_group_scoring = Boolean(settings.world_info_use_group_scoring); | 800 | world_info_use_group_scoring = Boolean(settings.world_info_use_group_scoring); |
| 801 | if (settings.world_info_max_recursion_steps !== undefined) | ||
| 802 | world_info_max_recursion_steps = Number(settings.world_info_max_recursion_steps); | ||
| 799 | 803 | ||
| 800 | // Migrate old settings | 804 | // Migrate old settings |
| 801 | if (world_info_budget > 100) { | 805 | if (world_info_budget > 100) { |
| @@ -844,6 +848,9 @@ export function setWorldInfoSettings(settings, data) { | |||
| 844 | $('#world_info_budget_cap').val(world_info_budget_cap); | 848 | $('#world_info_budget_cap').val(world_info_budget_cap); |
| 845 | $('#world_info_budget_cap_counter').val(world_info_budget_cap); | 849 | $('#world_info_budget_cap_counter').val(world_info_budget_cap); |
| 846 | 850 | ||
| 851 | $('#world_info_max_recursion_steps').val(world_info_max_recursion_steps); | ||
| 852 | $('#world_info_max_recursion_steps_counter').val(world_info_max_recursion_steps); | ||
| 853 | |||
| 847 | world_names = data.world_names?.length ? data.world_names : []; | 854 | world_names = data.world_names?.length ? data.world_names : []; |
| 848 | 855 | ||
| 849 | // Add to existing selected WI if it exists | 856 | // Add to existing selected WI if it exists |
| @@ -2459,7 +2466,7 @@ async function getWorldEntry(name, data, entry) { | |||
| 2459 | if (!isMobile()) { | 2466 | if (!isMobile()) { |
| 2460 | $(characterFilter).select2({ | 2467 | $(characterFilter).select2({ |
| 2461 | width: '100%', | 2468 | width: '100%', |
| 2462 | placeholder: 'All characters will pull from this entry.', | 2469 | placeholder: 'Tie this entry to specific characters or characters with specific tags', |
| 2463 | allowClear: true, | 2470 | allowClear: true, |
| 2464 | closeOnSelect: false, | 2471 | closeOnSelect: false, |
| 2465 | }); | 2472 | }); |
| @@ -3723,6 +3730,12 @@ export async function checkWorldInfo(chat, maxContext, isDryRun) { | |||
| 3723 | console.debug(`[WI] --- SEARCHING ENTRIES (on ${sortedEntries.length} entries) ---`); | 3730 | console.debug(`[WI] --- SEARCHING ENTRIES (on ${sortedEntries.length} entries) ---`); |
| 3724 | 3731 | ||
| 3725 | while (scanState) { | 3732 | while (scanState) { |
| 3733 | //if world_info_max_recursion_steps is non-zero min activations are disabled, and vice versa | ||
| 3734 | if (world_info_max_recursion_steps && world_info_max_recursion_steps <= count) { | ||
| 3735 | console.debug('[WI] Search stopped by reaching max recursion steps', world_info_max_recursion_steps); | ||
| 3736 | break; | ||
| 3737 | } | ||
| 3738 | |||
| 3726 | // Track how many times the loop has run. May be useful for debugging. | 3739 | // Track how many times the loop has run. May be useful for debugging. |
| 3727 | count++; | 3740 | count++; |
| 3728 | 3741 | ||
| @@ -4762,8 +4775,13 @@ jQuery(() => { | |||
| 4762 | 4775 | ||
| 4763 | $('#world_info_min_activations').on('input', function () { | 4776 | $('#world_info_min_activations').on('input', function () { |
| 4764 | world_info_min_activations = Number($(this).val()); | 4777 | world_info_min_activations = Number($(this).val()); |
| 4765 | $('#world_info_min_activations_counter').val($(this).val()); | 4778 | $('#world_info_min_activations_counter').val(world_info_min_activations); |
| 4779 | |||
| 4780 | if (world_info_min_activations !== 0) { | ||
| 4781 | $('#world_info_max_recursion_steps').val(0).trigger('input'); | ||
| 4782 | } else { | ||
| 4766 | saveSettings(); | 4783 | saveSettings(); |
| 4784 | } | ||
| 4767 | }); | 4785 | }); |
| 4768 | 4786 | ||
| 4769 | $('#world_info_min_activations_depth_max').on('input', function () { | 4787 | $('#world_info_min_activations_depth_max').on('input', function () { |
| @@ -4819,6 +4837,16 @@ jQuery(() => { | |||
| 4819 | saveSettings(); | 4837 | saveSettings(); |
| 4820 | }); | 4838 | }); |
| 4821 | 4839 | ||
| 4840 | $('#world_info_max_recursion_steps').on('input', function () { | ||
| 4841 | world_info_max_recursion_steps = Number($(this).val()); | ||
| 4842 | $('#world_info_max_recursion_steps_counter').val(world_info_max_recursion_steps); | ||
| 4843 | if (world_info_max_recursion_steps !== 0) { | ||
| 4844 | $('#world_info_min_activations').val(0).trigger('input'); | ||
| 4845 | } else { | ||
| 4846 | saveSettings(); | ||
| 4847 | } | ||
| 4848 | }); | ||
| 4849 | |||
| 4822 | $('#world_button').on('click', async function (event) { | 4850 | $('#world_button').on('click', async function (event) { |
| 4823 | const chid = $('#set_character_world').data('chid'); | 4851 | const chid = $('#set_character_world').data('chid'); |
| 4824 | 4852 | ||
| @@ -817,7 +817,7 @@ function createHttpsServer(url) { | |||
| 817 | }, app); | 817 | }, app); |
| 818 | server.on('error', reject); | 818 | server.on('error', reject); |
| 819 | server.on('listening', resolve); | 819 | server.on('listening', resolve); |
| 820 | server.listen(url.port, url.hostname); | 820 | server.listen(url.port || 443, url.hostname); |
| 821 | }); | 821 | }); |
| 822 | } | 822 | } |
| 823 | 823 | ||
| @@ -832,7 +832,7 @@ function createHttpServer(url) { | |||
| 832 | const server = http.createServer(app); | 832 | const server = http.createServer(app); |
| 833 | server.on('error', reject); | 833 | server.on('error', reject); |
| 834 | server.on('listening', resolve); | 834 | server.on('listening', resolve); |
| 835 | server.listen(url.port, url.hostname); | 835 | server.listen(url.port || 80, url.hostname); |
| 836 | }); | 836 | }); |
| 837 | } | 837 | } |
| 838 | 838 | ||
| @@ -0,0 +1,126 @@ | |||
| 1 | const DATA_PREFIX = 'data:'; | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Borrowed from Cohere SDK (MIT License) | ||
| 5 | * https://github.com/cohere-ai/cohere-typescript/blob/main/src/core/streaming-fetcher/Stream.ts | ||
| 6 | * Copyright (c) 2021 Cohere | ||
| 7 | */ | ||
| 8 | class CohereStream { | ||
| 9 | /** @type {ReadableStream} */ | ||
| 10 | stream; | ||
| 11 | /** @type {string} */ | ||
| 12 | prefix; | ||
| 13 | /** @type {string} */ | ||
| 14 | messageTerminator; | ||
| 15 | /** @type {string|undefined} */ | ||
| 16 | streamTerminator; | ||
| 17 | /** @type {AbortController} */ | ||
| 18 | controller = new AbortController(); | ||
| 19 | |||
| 20 | constructor({ stream, eventShape }) { | ||
| 21 | this.stream = stream; | ||
| 22 | if (eventShape.type === 'sse') { | ||
| 23 | this.prefix = DATA_PREFIX; | ||
| 24 | this.messageTerminator = '\n'; | ||
| 25 | this.streamTerminator = eventShape.streamTerminator; | ||
| 26 | } else { | ||
| 27 | this.messageTerminator = eventShape.messageTerminator; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | async *iterMessages() { | ||
| 32 | const stream = readableStreamAsyncIterable(this.stream); | ||
| 33 | let buf = ''; | ||
| 34 | let prefixSeen = false; | ||
| 35 | let parsedAnyMessages = false; | ||
| 36 | for await (const chunk of stream) { | ||
| 37 | buf += this.decodeChunk(chunk); | ||
| 38 | |||
| 39 | let terminatorIndex; | ||
| 40 | // Parse the chunk into as many messages as possible | ||
| 41 | while ((terminatorIndex = buf.indexOf(this.messageTerminator)) >= 0) { | ||
| 42 | // Extract the line from the buffer | ||
| 43 | let line = buf.slice(0, terminatorIndex + 1); | ||
| 44 | buf = buf.slice(terminatorIndex + 1); | ||
| 45 | |||
| 46 | // Skip empty lines | ||
| 47 | if (line.length === 0) { | ||
| 48 | continue; | ||
| 49 | } | ||
| 50 | |||
| 51 | // Skip the chunk until the prefix is found | ||
| 52 | if (!prefixSeen && this.prefix != null) { | ||
| 53 | const prefixIndex = line.indexOf(this.prefix); | ||
| 54 | if (prefixIndex === -1) { | ||
| 55 | continue; | ||
| 56 | } | ||
| 57 | prefixSeen = true; | ||
| 58 | line = line.slice(prefixIndex + this.prefix.length); | ||
| 59 | } | ||
| 60 | |||
| 61 | // If the stream terminator is present, return | ||
| 62 | if (this.streamTerminator != null && line.includes(this.streamTerminator)) { | ||
| 63 | return; | ||
| 64 | } | ||
| 65 | |||
| 66 | // Otherwise, yield message from the prefix to the terminator | ||
| 67 | const message = JSON.parse(line); | ||
| 68 | yield message; | ||
| 69 | prefixSeen = false; | ||
| 70 | parsedAnyMessages = true; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | if (!parsedAnyMessages && buf.length > 0) { | ||
| 75 | try { | ||
| 76 | yield JSON.parse(buf); | ||
| 77 | } catch (e) { | ||
| 78 | console.error('Error parsing message:', e); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | async *[Symbol.asyncIterator]() { | ||
| 84 | for await (const message of this.iterMessages()) { | ||
| 85 | yield message; | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | decodeChunk(chunk) { | ||
| 90 | const decoder = new TextDecoder('utf8'); | ||
| 91 | return decoder.decode(chunk); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | function readableStreamAsyncIterable(stream) { | ||
| 96 | if (stream[Symbol.asyncIterator]) { | ||
| 97 | return stream; | ||
| 98 | } | ||
| 99 | |||
| 100 | const reader = stream.getReader(); | ||
| 101 | return { | ||
| 102 | async next() { | ||
| 103 | try { | ||
| 104 | const result = await reader.read(); | ||
| 105 | if (result?.done) { | ||
| 106 | reader.releaseLock(); | ||
| 107 | } // release lock when stream becomes closed | ||
| 108 | return result; | ||
| 109 | } catch (e) { | ||
| 110 | reader.releaseLock(); // release lock when stream becomes errored | ||
| 111 | throw e; | ||
| 112 | } | ||
| 113 | }, | ||
| 114 | async return() { | ||
| 115 | const cancelPromise = reader.cancel(); | ||
| 116 | reader.releaseLock(); | ||
| 117 | await cancelPromise; | ||
| 118 | return { done: true, value: undefined }; | ||
| 119 | }, | ||
| 120 | [Symbol.asyncIterator]() { | ||
| 121 | return this; | ||
| 122 | }, | ||
| 123 | }; | ||
| 124 | } | ||
| 125 | |||
| 126 | module.exports = CohereStream; | ||
| @@ -1,11 +1,11 @@ | |||
| 1 | const express = require('express'); | 1 | const express = require('express'); |
| 2 | const fetch = require('node-fetch').default; | 2 | const fetch = require('node-fetch').default; |
| 3 | const Readable = require('stream').Readable; | ||
| 4 | 3 | ||
| 5 | const { jsonParser } = require('../../express-common'); | 4 | const { jsonParser } = require('../../express-common'); |
| 6 | const { CHAT_COMPLETION_SOURCES, GEMINI_SAFETY, BISON_SAFETY, OPENROUTER_HEADERS } = require('../../constants'); | 5 | const { CHAT_COMPLETION_SOURCES, GEMINI_SAFETY, BISON_SAFETY, OPENROUTER_HEADERS } = require('../../constants'); |
| 7 | const { forwardFetchResponse, getConfigValue, tryParse, uuidv4, mergeObjectWithYaml, excludeKeysByYaml, color } = require('../../util'); | 6 | const { forwardFetchResponse, getConfigValue, tryParse, uuidv4, mergeObjectWithYaml, excludeKeysByYaml, color } = require('../../util'); |
| 8 | const { convertClaudeMessages, convertGooglePrompt, convertTextCompletionPrompt, convertCohereMessages, convertMistralMessages, convertCohereTools } = require('../../prompt-converters'); | 7 | const { convertClaudeMessages, convertGooglePrompt, convertTextCompletionPrompt, convertCohereMessages, convertMistralMessages, convertCohereTools, convertAI21Messages } = require('../../prompt-converters'); |
| 8 | const CohereStream = require('../../cohere-stream'); | ||
| 9 | 9 | ||
| 10 | const { readSecret, SECRET_KEYS } = require('../secrets'); | 10 | const { readSecret, SECRET_KEYS } = require('../secrets'); |
| 11 | const { getTokenizerModel, getSentencepiceTokenizer, getTiktokenTokenizer, sentencepieceTokenizers, TEXT_COMPLETION_MODELS } = require('../tokenizers'); | 11 | const { getTokenizerModel, getSentencepiceTokenizer, getTiktokenTokenizer, sentencepieceTokenizers, TEXT_COMPLETION_MODELS } = require('../tokenizers'); |
| @@ -19,6 +19,7 @@ const API_GROQ = 'https://api.groq.com/openai/v1'; | |||
| 19 | const API_MAKERSUITE = 'https://generativelanguage.googleapis.com'; | 19 | const API_MAKERSUITE = 'https://generativelanguage.googleapis.com'; |
| 20 | const API_01AI = 'https://api.01.ai/v1'; | 20 | const API_01AI = 'https://api.01.ai/v1'; |
| 21 | const API_BLOCKENTROPY = 'https://api.blockentropy.ai/v1'; | 21 | const API_BLOCKENTROPY = 'https://api.blockentropy.ai/v1'; |
| 22 | const API_AI21 = 'https://api.ai21.com/studio/v1'; | ||
| 22 | 23 | ||
| 23 | /** | 24 | /** |
| 24 | * Applies a post-processing step to the generated messages. | 25 | * Applies a post-processing step to the generated messages. |
| @@ -40,52 +41,30 @@ function postProcessPrompt(messages, type, charName, userName) { | |||
| 40 | /** | 41 | /** |
| 41 | * Ollama strikes back. Special boy #2's steaming routine. | 42 | * Ollama strikes back. Special boy #2's steaming routine. |
| 42 | * Wrap this abomination into proper SSE stream, again. | 43 | * Wrap this abomination into proper SSE stream, again. |
| 43 | * @param {import('node-fetch').Response} jsonStream JSON stream | 44 | * @param {Response} jsonStream JSON stream |
| 44 | * @param {import('express').Request} request Express request | 45 | * @param {import('express').Request} request Express request |
| 45 | * @param {import('express').Response} response Express response | 46 | * @param {import('express').Response} response Express response |
| 46 | * @returns {Promise<any>} Nothing valuable | 47 | * @returns {Promise<any>} Nothing valuable |
| 47 | */ | 48 | */ |
| 48 | async function parseCohereStream(jsonStream, request, response) { | 49 | async function parseCohereStream(jsonStream, request, response) { |
| 49 | try { | 50 | try { |
| 50 | let partialData = ''; | 51 | const stream = new CohereStream({ stream: jsonStream.body, eventShape: { type: 'json', messageTerminator: '\n' } }); |
| 51 | jsonStream.body.on('data', (data) => { | 52 | |
| 52 | const chunk = data.toString(); | 53 | for await (const json of stream.iterMessages()) { |
| 53 | partialData += chunk; | ||
| 54 | while (true) { | ||
| 55 | let json; | ||
| 56 | try { | ||
| 57 | json = JSON.parse(partialData); | ||
| 58 | } catch (e) { | ||
| 59 | break; | ||
| 60 | } | ||
| 61 | if (json.message) { | 54 | if (json.message) { |
| 62 | const message = json.message || 'Unknown error'; | 55 | const message = json.message || 'Unknown error'; |
| 63 | const chunk = { error: { message: message } }; | 56 | const chunk = { error: { message: message } }; |
| 64 | response.write(`data: ${JSON.stringify(chunk)}\n\n`); | 57 | response.write(`data: ${JSON.stringify(chunk)}\n\n`); |
| 65 | partialData = ''; | ||
| 66 | break; | ||
| 67 | } else if (json.event_type === 'text-generation') { | 58 | } else if (json.event_type === 'text-generation') { |
| 68 | const text = json.text || ''; | 59 | const text = json.text || ''; |
| 69 | const chunk = { choices: [{ text }] }; | 60 | const chunk = { choices: [{ text }] }; |
| 70 | response.write(`data: ${JSON.stringify(chunk)}\n\n`); | 61 | response.write(`data: ${JSON.stringify(chunk)}\n\n`); |
| 71 | partialData = ''; | ||
| 72 | } else { | ||
| 73 | partialData = ''; | ||
| 74 | break; | ||
| 75 | } | 62 | } |
| 76 | } | 63 | } |
| 77 | }); | ||
| 78 | 64 | ||
| 79 | request.socket.on('close', function () { | ||
| 80 | if (jsonStream.body instanceof Readable) jsonStream.body.destroy(); | ||
| 81 | response.end(); | ||
| 82 | }); | ||
| 83 | |||
| 84 | jsonStream.body.on('end', () => { | ||
| 85 | console.log('Streaming request finished'); | 65 | console.log('Streaming request finished'); |
| 86 | response.write('data: [DONE]\n\n'); | 66 | response.write('data: [DONE]\n\n'); |
| 87 | response.end(); | 67 | response.end(); |
| 88 | }); | ||
| 89 | } catch (error) { | 68 | } catch (error) { |
| 90 | console.log('Error forwarding streaming response:', error); | 69 | console.log('Error forwarding streaming response:', error); |
| 91 | if (!response.headersSent) { | 70 | if (!response.headersSent) { |
| @@ -233,7 +212,7 @@ async function sendScaleRequest(request, response) { | |||
| 233 | 212 | ||
| 234 | if (!generateResponse.ok) { | 213 | if (!generateResponse.ok) { |
| 235 | console.log(`Scale API returned error: ${generateResponse.status} ${generateResponse.statusText} ${await generateResponse.text()}`); | 214 | console.log(`Scale API returned error: ${generateResponse.status} ${generateResponse.statusText} ${await generateResponse.text()}`); |
| 236 | return response.status(generateResponse.status).send({ error: true }); | 215 | return response.status(500).send({ error: true }); |
| 237 | } | 216 | } |
| 238 | 217 | ||
| 239 | const generateResponseJson = await generateResponse.json(); | 218 | const generateResponseJson = await generateResponse.json(); |
| @@ -259,7 +238,7 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 259 | const apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE); | 238 | const apiKey = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE); |
| 260 | 239 | ||
| 261 | if (!request.body.reverse_proxy && !apiKey) { | 240 | if (!request.body.reverse_proxy && !apiKey) { |
| 262 | console.log('MakerSuite API key is missing.'); | 241 | console.log('Google AI Studio API key is missing.'); |
| 263 | return response.status(400).send({ error: true }); | 242 | return response.status(400).send({ error: true }); |
| 264 | } | 243 | } |
| 265 | 244 | ||
| @@ -326,7 +305,7 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 326 | } | 305 | } |
| 327 | 306 | ||
| 328 | const body = isGemini ? getGeminiBody() : getBisonBody(); | 307 | const body = isGemini ? getGeminiBody() : getBisonBody(); |
| 329 | console.log('MakerSuite request:', body); | 308 | console.log('Google AI Studio request:', body); |
| 330 | 309 | ||
| 331 | try { | 310 | try { |
| 332 | const controller = new AbortController(); | 311 | const controller = new AbortController(); |
| @@ -362,7 +341,7 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 362 | } | 341 | } |
| 363 | } else { | 342 | } else { |
| 364 | if (!generateResponse.ok) { | 343 | if (!generateResponse.ok) { |
| 365 | console.log(`MakerSuite API returned error: ${generateResponse.status} ${generateResponse.statusText} ${await generateResponse.text()}`); | 344 | console.log(`Google AI Studio API returned error: ${generateResponse.status} ${generateResponse.statusText} ${await generateResponse.text()}`); |
| 366 | return response.status(generateResponse.status).send({ error: true }); | 345 | return response.status(generateResponse.status).send({ error: true }); |
| 367 | } | 346 | } |
| 368 | 347 | ||
| @@ -370,7 +349,7 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 370 | 349 | ||
| 371 | const candidates = generateResponseJson?.candidates; | 350 | const candidates = generateResponseJson?.candidates; |
| 372 | if (!candidates || candidates.length === 0) { | 351 | if (!candidates || candidates.length === 0) { |
| 373 | let message = 'MakerSuite API returned no candidate'; | 352 | let message = 'Google AI Studio API returned no candidate'; |
| 374 | console.log(message, generateResponseJson); | 353 | console.log(message, generateResponseJson); |
| 375 | if (generateResponseJson?.promptFeedback?.blockReason) { | 354 | if (generateResponseJson?.promptFeedback?.blockReason) { |
| 376 | message += `\nPrompt was blocked due to : ${generateResponseJson.promptFeedback.blockReason}`; | 355 | message += `\nPrompt was blocked due to : ${generateResponseJson.promptFeedback.blockReason}`; |
| @@ -381,19 +360,19 @@ async function sendMakerSuiteRequest(request, response) { | |||
| 381 | const responseContent = candidates[0].content ?? candidates[0].output; | 360 | const responseContent = candidates[0].content ?? candidates[0].output; |
| 382 | const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.[0]?.text; | 361 | const responseText = typeof responseContent === 'string' ? responseContent : responseContent?.parts?.[0]?.text; |
| 383 | if (!responseText) { | 362 | if (!responseText) { |
| 384 | let message = 'MakerSuite Candidate text empty'; | 363 | let message = 'Google AI Studio Candidate text empty'; |
| 385 | console.log(message, generateResponseJson); | 364 | console.log(message, generateResponseJson); |
| 386 | return response.send({ error: { message } }); | 365 | return response.send({ error: { message } }); |
| 387 | } | 366 | } |
| 388 | 367 | ||
| 389 | console.log('MakerSuite response:', responseText); | 368 | console.log('Google AI Studio response:', responseText); |
| 390 | 369 | ||
| 391 | // Wrap it back to OAI format | 370 | // Wrap it back to OAI format |
| 392 | const reply = { choices: [{ 'message': { 'content': responseText } }] }; | 371 | const reply = { choices: [{ 'message': { 'content': responseText } }] }; |
| 393 | return response.send(reply); | 372 | return response.send(reply); |
| 394 | } | 373 | } |
| 395 | } catch (error) { | 374 | } catch (error) { |
| 396 | console.log('Error communicating with MakerSuite API: ', error); | 375 | console.log('Error communicating with Google AI Studio API: ', error); |
| 397 | if (!response.headersSent) { | 376 | if (!response.headersSent) { |
| 398 | return response.status(500).send({ error: true }); | 377 | return response.status(500).send({ error: true }); |
| 399 | } | 378 | } |
| @@ -413,6 +392,16 @@ async function sendAI21Request(request, response) { | |||
| 413 | request.socket.on('close', function () { | 392 | request.socket.on('close', function () { |
| 414 | controller.abort(); | 393 | controller.abort(); |
| 415 | }); | 394 | }); |
| 395 | const convertedPrompt = convertAI21Messages(request.body.messages, request.body.char_name, request.body.user_name); | ||
| 396 | const body = { | ||
| 397 | messages: convertedPrompt, | ||
| 398 | model: request.body.model, | ||
| 399 | max_tokens: request.body.max_tokens, | ||
| 400 | temperature: request.body.temperature, | ||
| 401 | top_p: request.body.top_p, | ||
| 402 | stop: request.body.stop, | ||
| 403 | stream: request.body.stream, | ||
| 404 | }; | ||
| 416 | const options = { | 405 | const options = { |
| 417 | method: 'POST', | 406 | method: 'POST', |
| 418 | headers: { | 407 | headers: { |
| @@ -420,59 +409,35 @@ async function sendAI21Request(request, response) { | |||
| 420 | 'content-type': 'application/json', | 409 | 'content-type': 'application/json', |
| 421 | Authorization: `Bearer ${readSecret(request.user.directories, SECRET_KEYS.AI21)}`, | 410 | Authorization: `Bearer ${readSecret(request.user.directories, SECRET_KEYS.AI21)}`, |
| 422 | }, | 411 | }, |
| 423 | body: JSON.stringify({ | 412 | body: JSON.stringify(body), |
| 424 | numResults: 1, | ||
| 425 | maxTokens: request.body.max_tokens, | ||
| 426 | minTokens: 0, | ||
| 427 | temperature: request.body.temperature, | ||
| 428 | topP: request.body.top_p, | ||
| 429 | stopSequences: request.body.stop_tokens, | ||
| 430 | topKReturn: request.body.top_k, | ||
| 431 | frequencyPenalty: { | ||
| 432 | scale: request.body.frequency_penalty * 100, | ||
| 433 | applyToWhitespaces: false, | ||
| 434 | applyToPunctuations: false, | ||
| 435 | applyToNumbers: false, | ||
| 436 | applyToStopwords: false, | ||
| 437 | applyToEmojis: false, | ||
| 438 | }, | ||
| 439 | presencePenalty: { | ||
| 440 | scale: request.body.presence_penalty, | ||
| 441 | applyToWhitespaces: false, | ||
| 442 | applyToPunctuations: false, | ||
| 443 | applyToNumbers: false, | ||
| 444 | applyToStopwords: false, | ||
| 445 | applyToEmojis: false, | ||
| 446 | }, | ||
| 447 | countPenalty: { | ||
| 448 | scale: request.body.count_pen, | ||
| 449 | applyToWhitespaces: false, | ||
| 450 | applyToPunctuations: false, | ||
| 451 | applyToNumbers: false, | ||
| 452 | applyToStopwords: false, | ||
| 453 | applyToEmojis: false, | ||
| 454 | }, | ||
| 455 | prompt: request.body.messages, | ||
| 456 | }), | ||
| 457 | signal: controller.signal, | 413 | signal: controller.signal, |
| 458 | }; | 414 | }; |
| 459 | 415 | ||
| 460 | fetch(`https://api.ai21.com/studio/v1/${request.body.model}/complete`, options) | 416 | console.log('AI21 request:', body); |
| 461 | .then(r => r.json()) | 417 | |
| 462 | .then(r => { | 418 | try { |
| 463 | if (r.completions === undefined) { | 419 | const generateResponse = await fetch(API_AI21 + '/chat/completions', options); |
| 464 | console.log(r); | 420 | if (request.body.stream) { |
| 421 | forwardFetchResponse(generateResponse, response); | ||
| 465 | } else { | 422 | } else { |
| 466 | console.log(r.completions[0].data.text); | 423 | if (!generateResponse.ok) { |
| 424 | const errorText = await generateResponse.text(); | ||
| 425 | console.log(`AI21 API returned error: ${generateResponse.status} ${generateResponse.statusText} ${errorText}`); | ||
| 426 | const errorJson = tryParse(errorText) ?? { error: true }; | ||
| 427 | return response.status(500).send(errorJson); | ||
| 428 | } | ||
| 429 | const generateResponseJson = await generateResponse.json(); | ||
| 430 | console.log('AI21 response:', generateResponseJson); | ||
| 431 | return response.send(generateResponseJson); | ||
| 432 | } | ||
| 433 | } catch (error) { | ||
| 434 | console.log('Error communicating with AI21 API: ', error); | ||
| 435 | if (!response.headersSent) { | ||
| 436 | response.send({ error: true }); | ||
| 437 | } else { | ||
| 438 | response.end(); | ||
| 439 | } | ||
| 467 | } | 440 | } |
| 468 | const reply = { choices: [{ 'message': { 'content': r.completions?.[0]?.data?.text } }] }; | ||
| 469 | return response.send(reply); | ||
| 470 | }) | ||
| 471 | .catch(err => { | ||
| 472 | console.error(err); | ||
| 473 | return response.send({ error: true }); | ||
| 474 | }); | ||
| 475 | |||
| 476 | } | 441 | } |
| 477 | 442 | ||
| 478 | /** | 443 | /** |
| @@ -531,10 +496,10 @@ async function sendMistralAIRequest(request, response) { | |||
| 531 | forwardFetchResponse(generateResponse, response); | 496 | forwardFetchResponse(generateResponse, response); |
| 532 | } else { | 497 | } else { |
| 533 | if (!generateResponse.ok) { | 498 | if (!generateResponse.ok) { |
| 534 | console.log(`MistralAI API returned error: ${generateResponse.status} ${generateResponse.statusText} ${await generateResponse.text()}`); | 499 | const errorText = await generateResponse.text(); |
| 535 | // a 401 unauthorized response breaks the frontend auth, so return a 500 instead. prob a better way of dealing with this. | 500 | console.log(`MistralAI API returned error: ${generateResponse.status} ${generateResponse.statusText} ${errorText}`); |
| 536 | // 401s are already handled by the streaming processor and dont pop up an error toast, that should probably be fixed too. | 501 | const errorJson = tryParse(errorText) ?? { error: true }; |
| 537 | return response.status(generateResponse.status === 401 ? 500 : generateResponse.status).send({ error: true }); | 502 | return response.status(500).send(errorJson); |
| 538 | } | 503 | } |
| 539 | const generateResponseJson = await generateResponse.json(); | 504 | const generateResponseJson = await generateResponse.json(); |
| 540 | console.log('MistralAI response:', generateResponseJson); | 505 | console.log('MistralAI response:', generateResponseJson); |
| @@ -607,6 +572,11 @@ async function sendCohereRequest(request, response) { | |||
| 607 | search_queries_only: false, | 572 | search_queries_only: false, |
| 608 | }; | 573 | }; |
| 609 | 574 | ||
| 575 | const canDoSafetyMode = String(request.body.model).endsWith('08-2024'); | ||
| 576 | if (canDoSafetyMode) { | ||
| 577 | requestBody.safety_mode = 'NONE'; | ||
| 578 | } | ||
| 579 | |||
| 610 | console.log('Cohere request:', requestBody); | 580 | console.log('Cohere request:', requestBody); |
| 611 | 581 | ||
| 612 | const config = { | 582 | const config = { |
| @@ -623,15 +593,15 @@ async function sendCohereRequest(request, response) { | |||
| 623 | const apiUrl = API_COHERE + '/chat'; | 593 | const apiUrl = API_COHERE + '/chat'; |
| 624 | 594 | ||
| 625 | if (request.body.stream) { | 595 | if (request.body.stream) { |
| 626 | const stream = await fetch(apiUrl, config); | 596 | const stream = await global.fetch(apiUrl, config); |
| 627 | parseCohereStream(stream, request, response); | 597 | parseCohereStream(stream, request, response); |
| 628 | } else { | 598 | } else { |
| 629 | const generateResponse = await fetch(apiUrl, config); | 599 | const generateResponse = await fetch(apiUrl, config); |
| 630 | if (!generateResponse.ok) { | 600 | if (!generateResponse.ok) { |
| 631 | console.log(`Cohere API returned error: ${generateResponse.status} ${generateResponse.statusText} ${await generateResponse.text()}`); | 601 | const errorText = await generateResponse.text(); |
| 632 | // a 401 unauthorized response breaks the frontend auth, so return a 500 instead. prob a better way of dealing with this. | 602 | console.log(`Cohere API returned error: ${generateResponse.status} ${generateResponse.statusText} ${errorText}`); |
| 633 | // 401s are already handled by the streaming processor and dont pop up an error toast, that should probably be fixed too. | 603 | const errorJson = tryParse(errorText) ?? { error: true }; |
| 634 | return response.status(generateResponse.status === 401 ? 500 : generateResponse.status).send({ error: true }); | 604 | return response.status(500).send(errorJson); |
| 635 | } | 605 | } |
| 636 | const generateResponseJson = await generateResponse.json(); | 606 | const generateResponseJson = await generateResponse.json(); |
| 637 | console.log('Cohere response:', generateResponseJson); | 607 | console.log('Cohere response:', generateResponseJson); |
| @@ -44,7 +44,7 @@ router.post('/caption-image', jsonParser, async (request, response) => { | |||
| 44 | 44 | ||
| 45 | if (!result.ok) { | 45 | if (!result.ok) { |
| 46 | const error = await result.json(); | 46 | const error = await result.json(); |
| 47 | console.log(`MakerSuite API returned error: ${result.status} ${result.statusText}`, error); | 47 | console.log(`Google AI Studio API returned error: ${result.status} ${result.statusText}`, error); |
| 48 | return response.status(result.status).send({ error: true }); | 48 | return response.status(result.status).send({ error: true }); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| @@ -6,6 +6,7 @@ const { readAllChunks, extractFileFromZipBuffer, forwardFetchResponse } = requir | |||
| 6 | const { jsonParser } = require('../express-common'); | 6 | const { jsonParser } = require('../express-common'); |
| 7 | 7 | ||
| 8 | const API_NOVELAI = 'https://api.novelai.net'; | 8 | const API_NOVELAI = 'https://api.novelai.net'; |
| 9 | const TEXT_NOVELAI = 'https://text.novelai.net'; | ||
| 9 | const IMAGE_NOVELAI = 'https://image.novelai.net'; | 10 | const IMAGE_NOVELAI = 'https://image.novelai.net'; |
| 10 | 11 | ||
| 11 | // Ban bracket generation, plus defaults | 12 | // Ban bracket generation, plus defaults |
| @@ -155,7 +156,7 @@ router.post('/generate', jsonParser, async function (req, res) { | |||
| 155 | 'repetition_penalty_slope': req.body.repetition_penalty_slope, | 156 | 'repetition_penalty_slope': req.body.repetition_penalty_slope, |
| 156 | 'repetition_penalty_frequency': req.body.repetition_penalty_frequency, | 157 | 'repetition_penalty_frequency': req.body.repetition_penalty_frequency, |
| 157 | 'repetition_penalty_presence': req.body.repetition_penalty_presence, | 158 | 'repetition_penalty_presence': req.body.repetition_penalty_presence, |
| 158 | 'repetition_penalty_whitelist': isNewModel ? repPenaltyAllowList : null, | 159 | 'repetition_penalty_whitelist': isNewModel ? repPenaltyAllowList.flat() : null, |
| 159 | 'top_a': req.body.top_a, | 160 | 'top_a': req.body.top_a, |
| 160 | 'top_p': req.body.top_p, | 161 | 'top_p': req.body.top_p, |
| 161 | 'top_k': req.body.top_k, | 162 | 'top_k': req.body.top_k, |
| @@ -178,9 +179,7 @@ router.post('/generate', jsonParser, async function (req, res) { | |||
| 178 | }; | 179 | }; |
| 179 | 180 | ||
| 180 | // Tells the model to stop generation at '>' | 181 | // Tells the model to stop generation at '>' |
| 181 | if ('theme_textadventure' === req.body.prefix && | 182 | if ('theme_textadventure' === req.body.prefix && isNewModel) { |
| 182 | (true === req.body.model.includes('clio') || | ||
| 183 | true === req.body.model.includes('kayra'))) { | ||
| 184 | data.parameters.eos_token_id = 49405; | 183 | data.parameters.eos_token_id = 49405; |
| 185 | } | 184 | } |
| 186 | 185 | ||
| @@ -193,7 +192,8 @@ router.post('/generate', jsonParser, async function (req, res) { | |||
| 193 | }; | 192 | }; |
| 194 | 193 | ||
| 195 | try { | 194 | try { |
| 196 | const url = req.body.streaming ? `${API_NOVELAI}/ai/generate-stream` : `${API_NOVELAI}/ai/generate`; | 195 | const baseURL = req.body.model.includes('kayra') ? TEXT_NOVELAI : API_NOVELAI; |
| 196 | const url = req.body.streaming ? `${baseURL}/ai/generate-stream` : `${baseURL}/ai/generate`; | ||
| 197 | const response = await fetch(url, { method: 'POST', timeout: 0, ...args }); | 197 | const response = await fetch(url, { method: 'POST', timeout: 0, ...args }); |
| 198 | 198 | ||
| 199 | if (req.body.streaming) { | 199 | if (req.body.streaming) { |
| @@ -9,6 +9,7 @@ const { jsonParser } = require('../express-common'); | |||
| 9 | const { getAllUserHandles, getUserDirectories } = require('../users'); | 9 | const { getAllUserHandles, getUserDirectories } = require('../users'); |
| 10 | 10 | ||
| 11 | const ENABLE_EXTENSIONS = getConfigValue('enableExtensions', true); | 11 | const ENABLE_EXTENSIONS = getConfigValue('enableExtensions', true); |
| 12 | const ENABLE_EXTENSIONS_AUTO_UPDATE = getConfigValue('enableExtensionsAutoUpdate', true); | ||
| 12 | const ENABLE_ACCOUNTS = getConfigValue('enableUserAccounts', false); | 13 | const ENABLE_ACCOUNTS = getConfigValue('enableUserAccounts', false); |
| 13 | 14 | ||
| 14 | // 10 minutes | 15 | // 10 minutes |
| @@ -268,6 +269,7 @@ router.post('/get', jsonParser, (request, response) => { | |||
| 268 | instruct, | 269 | instruct, |
| 269 | context, | 270 | context, |
| 270 | enable_extensions: ENABLE_EXTENSIONS, | 271 | enable_extensions: ENABLE_EXTENSIONS, |
| 272 | enable_extensions_auto_update: ENABLE_EXTENSIONS_AUTO_UPDATE, | ||
| 271 | enable_accounts: ENABLE_ACCOUNTS, | 273 | enable_accounts: ENABLE_ACCOUNTS, |
| 272 | }); | 274 | }); |
| 273 | }); | 275 | }); |
| @@ -991,11 +991,52 @@ blockentropy.post('/generate', jsonParser, async (request, response) => { | |||
| 991 | }); | 991 | }); |
| 992 | 992 | ||
| 993 | 993 | ||
| 994 | const huggingface = express.Router(); | ||
| 995 | |||
| 996 | huggingface.post('/generate', jsonParser, async (request, response) => { | ||
| 997 | try { | ||
| 998 | const key = readSecret(request.user.directories, SECRET_KEYS.HUGGINGFACE); | ||
| 999 | |||
| 1000 | if (!key) { | ||
| 1001 | console.log('Hugging Face key not found.'); | ||
| 1002 | return response.sendStatus(400); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | console.log('Hugging Face request:', request.body); | ||
| 1006 | |||
| 1007 | const result = await fetch(`https://api-inference.huggingface.co/models/${request.body.model}`, { | ||
| 1008 | method: 'POST', | ||
| 1009 | body: JSON.stringify({ | ||
| 1010 | inputs: request.body.prompt, | ||
| 1011 | }), | ||
| 1012 | headers: { | ||
| 1013 | 'Content-Type': 'application/json', | ||
| 1014 | 'Authorization': `Bearer ${key}`, | ||
| 1015 | }, | ||
| 1016 | }); | ||
| 1017 | |||
| 1018 | if (!result.ok) { | ||
| 1019 | console.log('Hugging Face returned an error.'); | ||
| 1020 | return response.sendStatus(500); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | const buffer = await result.buffer(); | ||
| 1024 | return response.send({ | ||
| 1025 | image: buffer.toString('base64'), | ||
| 1026 | }); | ||
| 1027 | } catch (error) { | ||
| 1028 | console.log(error); | ||
| 1029 | return response.sendStatus(500); | ||
| 1030 | } | ||
| 1031 | }); | ||
| 1032 | |||
| 1033 | |||
| 994 | router.use('/comfy', comfy); | 1034 | router.use('/comfy', comfy); |
| 995 | router.use('/together', together); | 1035 | router.use('/together', together); |
| 996 | router.use('/drawthings', drawthings); | 1036 | router.use('/drawthings', drawthings); |
| 997 | router.use('/pollinations', pollinations); | 1037 | router.use('/pollinations', pollinations); |
| 998 | router.use('/stability', stability); | 1038 | router.use('/stability', stability); |
| 999 | router.use('/blockentropy', blockentropy); | 1039 | router.use('/blockentropy', blockentropy); |
| 1040 | router.use('/huggingface', huggingface); | ||
| 1000 | 1041 | ||
| 1001 | module.exports = { router }; | 1042 | module.exports = { router }; |
| @@ -144,6 +144,7 @@ const spp_nerd_v2 = new SentencePieceTokenizer('src/tokenizers/nerdstash_v2.mode | |||
| 144 | const spp_mistral = new SentencePieceTokenizer('src/tokenizers/mistral.model'); | 144 | const spp_mistral = new SentencePieceTokenizer('src/tokenizers/mistral.model'); |
| 145 | const spp_yi = new SentencePieceTokenizer('src/tokenizers/yi.model'); | 145 | const spp_yi = new SentencePieceTokenizer('src/tokenizers/yi.model'); |
| 146 | const spp_gemma = new SentencePieceTokenizer('src/tokenizers/gemma.model'); | 146 | const spp_gemma = new SentencePieceTokenizer('src/tokenizers/gemma.model'); |
| 147 | const spp_jamba = new SentencePieceTokenizer('src/tokenizers/jamba.model'); | ||
| 147 | const claude_tokenizer = new WebTokenizer('src/tokenizers/claude.json'); | 148 | const claude_tokenizer = new WebTokenizer('src/tokenizers/claude.json'); |
| 148 | const llama3_tokenizer = new WebTokenizer('src/tokenizers/llama3.json'); | 149 | const llama3_tokenizer = new WebTokenizer('src/tokenizers/llama3.json'); |
| 149 | 150 | ||
| @@ -154,6 +155,7 @@ const sentencepieceTokenizers = [ | |||
| 154 | 'mistral', | 155 | 'mistral', |
| 155 | 'yi', | 156 | 'yi', |
| 156 | 'gemma', | 157 | 'gemma', |
| 158 | 'jamba', | ||
| 157 | ]; | 159 | ]; |
| 158 | 160 | ||
| 159 | /** | 161 | /** |
| @@ -186,6 +188,10 @@ function getSentencepiceTokenizer(model) { | |||
| 186 | return spp_gemma; | 188 | return spp_gemma; |
| 187 | } | 189 | } |
| 188 | 190 | ||
| 191 | if (model.includes('jamba')) { | ||
| 192 | return spp_jamba; | ||
| 193 | } | ||
| 194 | |||
| 189 | return null; | 195 | return null; |
| 190 | } | 196 | } |
| 191 | 197 | ||
| @@ -322,6 +328,10 @@ function getTokenizerModel(requestModel) { | |||
| 322 | return 'gemma'; | 328 | return 'gemma'; |
| 323 | } | 329 | } |
| 324 | 330 | ||
| 331 | if (requestModel.includes('jamba')) { | ||
| 332 | return 'jamba'; | ||
| 333 | } | ||
| 334 | |||
| 325 | // default | 335 | // default |
| 326 | return 'gpt-3.5-turbo'; | 336 | return 'gpt-3.5-turbo'; |
| 327 | } | 337 | } |
| @@ -537,59 +547,13 @@ function createWebTokenizerDecodingHandler(tokenizer) { | |||
| 537 | 547 | ||
| 538 | const router = express.Router(); | 548 | const router = express.Router(); |
| 539 | 549 | ||
| 540 | router.post('/ai21/count', jsonParser, async function (req, res) { | ||
| 541 | if (!req.body) return res.sendStatus(400); | ||
| 542 | const key = readSecret(req.user.directories, SECRET_KEYS.AI21); | ||
| 543 | const options = { | ||
| 544 | method: 'POST', | ||
| 545 | headers: { | ||
| 546 | accept: 'application/json', | ||
| 547 | 'content-type': 'application/json', | ||
| 548 | Authorization: `Bearer ${key}`, | ||
| 549 | }, | ||
| 550 | body: JSON.stringify({ text: req.body[0].content }), | ||
| 551 | }; | ||
| 552 | |||
| 553 | try { | ||
| 554 | const response = await fetch('https://api.ai21.com/studio/v1/tokenize', options); | ||
| 555 | const data = await response.json(); | ||
| 556 | return res.send({ 'token_count': data?.tokens?.length || 0 }); | ||
| 557 | } catch (err) { | ||
| 558 | console.error(err); | ||
| 559 | return res.send({ 'token_count': 0 }); | ||
| 560 | } | ||
| 561 | }); | ||
| 562 | |||
| 563 | router.post('/google/count', jsonParser, async function (req, res) { | ||
| 564 | if (!req.body) return res.sendStatus(400); | ||
| 565 | const options = { | ||
| 566 | method: 'POST', | ||
| 567 | headers: { | ||
| 568 | accept: 'application/json', | ||
| 569 | 'content-type': 'application/json', | ||
| 570 | }, | ||
| 571 | body: JSON.stringify({ contents: convertGooglePrompt(req.body, String(req.query.model)).contents }), | ||
| 572 | }; | ||
| 573 | try { | ||
| 574 | const reverseProxy = req.query.reverse_proxy?.toString() || ''; | ||
| 575 | const proxyPassword = req.query.proxy_password?.toString() || ''; | ||
| 576 | const apiKey = reverseProxy ? proxyPassword : readSecret(req.user.directories, SECRET_KEYS.MAKERSUITE); | ||
| 577 | const apiUrl = new URL(reverseProxy || API_MAKERSUITE); | ||
| 578 | const response = await fetch(`${apiUrl.origin}/v1beta/models/${req.query.model}:countTokens?key=${apiKey}`, options); | ||
| 579 | const data = await response.json(); | ||
| 580 | return res.send({ 'token_count': data?.totalTokens || 0 }); | ||
| 581 | } catch (err) { | ||
| 582 | console.error(err); | ||
| 583 | return res.send({ 'token_count': 0 }); | ||
| 584 | } | ||
| 585 | }); | ||
| 586 | |||
| 587 | router.post('/llama/encode', jsonParser, createSentencepieceEncodingHandler(spp_llama)); | 550 | router.post('/llama/encode', jsonParser, createSentencepieceEncodingHandler(spp_llama)); |
| 588 | router.post('/nerdstash/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd)); | 551 | router.post('/nerdstash/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd)); |
| 589 | router.post('/nerdstash_v2/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd_v2)); | 552 | router.post('/nerdstash_v2/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd_v2)); |
| 590 | router.post('/mistral/encode', jsonParser, createSentencepieceEncodingHandler(spp_mistral)); | 553 | router.post('/mistral/encode', jsonParser, createSentencepieceEncodingHandler(spp_mistral)); |
| 591 | router.post('/yi/encode', jsonParser, createSentencepieceEncodingHandler(spp_yi)); | 554 | router.post('/yi/encode', jsonParser, createSentencepieceEncodingHandler(spp_yi)); |
| 592 | router.post('/gemma/encode', jsonParser, createSentencepieceEncodingHandler(spp_gemma)); | 555 | router.post('/gemma/encode', jsonParser, createSentencepieceEncodingHandler(spp_gemma)); |
| 556 | router.post('/jamba/encode', jsonParser, createSentencepieceEncodingHandler(spp_jamba)); | ||
| 593 | router.post('/gpt2/encode', jsonParser, createTiktokenEncodingHandler('gpt2')); | 557 | router.post('/gpt2/encode', jsonParser, createTiktokenEncodingHandler('gpt2')); |
| 594 | router.post('/claude/encode', jsonParser, createWebTokenizerEncodingHandler(claude_tokenizer)); | 558 | router.post('/claude/encode', jsonParser, createWebTokenizerEncodingHandler(claude_tokenizer)); |
| 595 | router.post('/llama3/encode', jsonParser, createWebTokenizerEncodingHandler(llama3_tokenizer)); | 559 | router.post('/llama3/encode', jsonParser, createWebTokenizerEncodingHandler(llama3_tokenizer)); |
| @@ -599,6 +563,7 @@ router.post('/nerdstash_v2/decode', jsonParser, createSentencepieceDecodingHandl | |||
| 599 | router.post('/mistral/decode', jsonParser, createSentencepieceDecodingHandler(spp_mistral)); | 563 | router.post('/mistral/decode', jsonParser, createSentencepieceDecodingHandler(spp_mistral)); |
| 600 | router.post('/yi/decode', jsonParser, createSentencepieceDecodingHandler(spp_yi)); | 564 | router.post('/yi/decode', jsonParser, createSentencepieceDecodingHandler(spp_yi)); |
| 601 | router.post('/gemma/decode', jsonParser, createSentencepieceDecodingHandler(spp_gemma)); | 565 | router.post('/gemma/decode', jsonParser, createSentencepieceDecodingHandler(spp_gemma)); |
| 566 | router.post('/jamba/decode', jsonParser, createSentencepieceDecodingHandler(spp_jamba)); | ||
| 602 | router.post('/gpt2/decode', jsonParser, createTiktokenDecodingHandler('gpt2')); | 567 | router.post('/gpt2/decode', jsonParser, createTiktokenDecodingHandler('gpt2')); |
| 603 | router.post('/claude/decode', jsonParser, createWebTokenizerDecodingHandler(claude_tokenizer)); | 568 | router.post('/claude/decode', jsonParser, createWebTokenizerDecodingHandler(claude_tokenizer)); |
| 604 | router.post('/llama3/decode', jsonParser, createWebTokenizerDecodingHandler(llama3_tokenizer)); | 569 | router.post('/llama3/decode', jsonParser, createWebTokenizerDecodingHandler(llama3_tokenizer)); |
| @@ -637,6 +602,11 @@ router.post('/openai/encode', jsonParser, async function (req, res) { | |||
| 637 | return handler(req, res); | 602 | return handler(req, res); |
| 638 | } | 603 | } |
| 639 | 604 | ||
| 605 | if (queryModel.includes('jamba')) { | ||
| 606 | const handler = createSentencepieceEncodingHandler(spp_jamba); | ||
| 607 | return handler(req, res); | ||
| 608 | } | ||
| 609 | |||
| 640 | const model = getTokenizerModel(queryModel); | 610 | const model = getTokenizerModel(queryModel); |
| 641 | const handler = createTiktokenEncodingHandler(model); | 611 | const handler = createTiktokenEncodingHandler(model); |
| 642 | return handler(req, res); | 612 | return handler(req, res); |
| @@ -680,6 +650,11 @@ router.post('/openai/decode', jsonParser, async function (req, res) { | |||
| 680 | return handler(req, res); | 650 | return handler(req, res); |
| 681 | } | 651 | } |
| 682 | 652 | ||
| 653 | if (queryModel.includes('jamba')) { | ||
| 654 | const handler = createSentencepieceDecodingHandler(spp_jamba); | ||
| 655 | return handler(req, res); | ||
| 656 | } | ||
| 657 | |||
| 683 | const model = getTokenizerModel(queryModel); | 658 | const model = getTokenizerModel(queryModel); |
| 684 | const handler = createTiktokenDecodingHandler(model); | 659 | const handler = createTiktokenDecodingHandler(model); |
| 685 | return handler(req, res); | 660 | return handler(req, res); |
| @@ -731,6 +706,11 @@ router.post('/openai/count', jsonParser, async function (req, res) { | |||
| 731 | return res.send({ 'token_count': num_tokens }); | 706 | return res.send({ 'token_count': num_tokens }); |
| 732 | } | 707 | } |
| 733 | 708 | ||
| 709 | if (model === 'jamba') { | ||
| 710 | num_tokens = await countSentencepieceArrayTokens(spp_jamba, req.body); | ||
| 711 | return res.send({ 'token_count': num_tokens }); | ||
| 712 | } | ||
| 713 | |||
| 734 | const tokensPerName = queryModel.includes('gpt-3.5-turbo-0301') ? -1 : 1; | 714 | const tokensPerName = queryModel.includes('gpt-3.5-turbo-0301') ? -1 : 1; |
| 735 | const tokensPerMessage = queryModel.includes('gpt-3.5-turbo-0301') ? 4 : 3; | 715 | const tokensPerMessage = queryModel.includes('gpt-3.5-turbo-0301') ? 4 : 3; |
| 736 | const tokensPadding = 3; | 716 | const tokensPadding = 3; |
| @@ -812,6 +792,7 @@ router.post('/remote/textgenerationwebui/encode', jsonParser, async function (re | |||
| 812 | const baseUrl = String(request.body.url); | 792 | const baseUrl = String(request.body.url); |
| 813 | const legacyApi = Boolean(request.body.legacy_api); | 793 | const legacyApi = Boolean(request.body.legacy_api); |
| 814 | const vllmModel = String(request.body.vllm_model) || ''; | 794 | const vllmModel = String(request.body.vllm_model) || ''; |
| 795 | const aphroditeModel = String(request.body.aphrodite_model) || ''; | ||
| 815 | 796 | ||
| 816 | try { | 797 | try { |
| 817 | const args = { | 798 | const args = { |
| @@ -847,7 +828,7 @@ router.post('/remote/textgenerationwebui/encode', jsonParser, async function (re | |||
| 847 | break; | 828 | break; |
| 848 | case TEXTGEN_TYPES.APHRODITE: | 829 | case TEXTGEN_TYPES.APHRODITE: |
| 849 | url += '/v1/tokenize'; | 830 | url += '/v1/tokenize'; |
| 850 | args.body = JSON.stringify({ 'prompt': text }); | 831 | args.body = JSON.stringify({ 'model': aphroditeModel, 'prompt': text }); |
| 851 | break; | 832 | break; |
| 852 | default: | 833 | default: |
| 853 | url += '/v1/internal/encode'; | 834 | url += '/v1/internal/encode'; |
| @@ -110,6 +110,7 @@ router.post('/google', jsonParser, async (request, response) => { | |||
| 110 | }); | 110 | }); |
| 111 | 111 | ||
| 112 | router.post('/yandex', jsonParser, async (request, response) => { | 112 | router.post('/yandex', jsonParser, async (request, response) => { |
| 113 | try { | ||
| 113 | const chunks = request.body.chunks; | 114 | const chunks = request.body.chunks; |
| 114 | const lang = request.body.lang; | 115 | const lang = request.body.lang; |
| 115 | 116 | ||
| @@ -130,7 +131,6 @@ router.post('/yandex', jsonParser, async (request, response) => { | |||
| 130 | 131 | ||
| 131 | console.log('Input text: ' + inputText); | 132 | console.log('Input text: ' + inputText); |
| 132 | 133 | ||
| 133 | try { | ||
| 134 | const result = await fetch(`https://translate.yandex.net/api/v1/tr.json/translate?ucid=${ucid}&srv=android&format=text`, { | 134 | const result = await fetch(`https://translate.yandex.net/api/v1/tr.json/translate?ucid=${ucid}&srv=android&format=text`, { |
| 135 | method: 'POST', | 135 | method: 'POST', |
| 136 | body: params, | 136 | body: params, |
| @@ -267,10 +267,13 @@ function convertGooglePrompt(messages, model, useSysPrompt = false, charName = ' | |||
| 267 | 'gemini-1.5-flash', | 267 | 'gemini-1.5-flash', |
| 268 | 'gemini-1.5-flash-latest', | 268 | 'gemini-1.5-flash-latest', |
| 269 | 'gemini-1.5-flash-001', | 269 | 'gemini-1.5-flash-001', |
| 270 | 'gemini-1.5-flash-exp-0827', | ||
| 271 | 'gemini-1.5-flash-8b-exp-0827', | ||
| 270 | 'gemini-1.5-pro', | 272 | 'gemini-1.5-pro', |
| 271 | 'gemini-1.5-pro-latest', | 273 | 'gemini-1.5-pro-latest', |
| 272 | 'gemini-1.5-pro-001', | 274 | 'gemini-1.5-pro-001', |
| 273 | 'gemini-1.5-pro-exp-0801', | 275 | 'gemini-1.5-pro-exp-0801', |
| 276 | 'gemini-1.5-pro-exp-0827', | ||
| 274 | 'gemini-1.0-pro-vision-latest', | 277 | 'gemini-1.0-pro-vision-latest', |
| 275 | 'gemini-pro-vision', | 278 | 'gemini-pro-vision', |
| 276 | ]; | 279 | ]; |
| @@ -368,6 +371,78 @@ function convertGooglePrompt(messages, model, useSysPrompt = false, charName = ' | |||
| 368 | } | 371 | } |
| 369 | 372 | ||
| 370 | /** | 373 | /** |
| 374 | * Convert AI21 prompt. Classic: system message squash, user/assistant message merge. | ||
| 375 | * @param {object[]} messages Array of messages | ||
| 376 | * @param {string} charName Character name | ||
| 377 | * @param {string} userName User name | ||
| 378 | */ | ||
| 379 | function convertAI21Messages(messages, charName = '', userName = '') { | ||
| 380 | if (!Array.isArray(messages)) { | ||
| 381 | return []; | ||
| 382 | } | ||
| 383 | |||
| 384 | // Collect all the system messages up until the first instance of a non-system message, and then remove them from the messages array. | ||
| 385 | let i = 0, systemPrompt = ''; | ||
| 386 | |||
| 387 | for (i = 0; i < messages.length; i++) { | ||
| 388 | if (messages[i].role !== 'system') { | ||
| 389 | break; | ||
| 390 | } | ||
| 391 | // Append example names if not already done by the frontend (e.g. for group chats). | ||
| 392 | if (userName && messages[i].name === 'example_user') { | ||
| 393 | if (!messages[i].content.startsWith(`${userName}: `)) { | ||
| 394 | messages[i].content = `${userName}: ${messages[i].content}`; | ||
| 395 | } | ||
| 396 | } | ||
| 397 | if (charName && messages[i].name === 'example_assistant') { | ||
| 398 | if (!messages[i].content.startsWith(`${charName}: `)) { | ||
| 399 | messages[i].content = `${charName}: ${messages[i].content}`; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | systemPrompt += `${messages[i].content}\n\n`; | ||
| 403 | } | ||
| 404 | |||
| 405 | messages.splice(0, i); | ||
| 406 | |||
| 407 | // Prevent erroring out if the messages array is empty. | ||
| 408 | if (messages.length === 0) { | ||
| 409 | messages.unshift({ | ||
| 410 | role: 'user', | ||
| 411 | content: '[Start a new chat]', | ||
| 412 | }); | ||
| 413 | } | ||
| 414 | |||
| 415 | if (systemPrompt) { | ||
| 416 | messages.unshift({ | ||
| 417 | role: 'system', | ||
| 418 | content: systemPrompt.trim(), | ||
| 419 | }); | ||
| 420 | } | ||
| 421 | |||
| 422 | // Doesn't support completion names, so prepend if not already done by the frontend (e.g. for group chats). | ||
| 423 | messages.forEach(msg => { | ||
| 424 | if ('name' in msg) { | ||
| 425 | if (msg.role !== 'system' && !msg.content.startsWith(`${msg.name}: `)) { | ||
| 426 | msg.content = `${msg.name}: ${msg.content}`; | ||
| 427 | } | ||
| 428 | delete msg.name; | ||
| 429 | } | ||
| 430 | }); | ||
| 431 | |||
| 432 | // Since the messaging endpoint only supports alternating turns, we have to merge messages with the same role if they follow each other | ||
| 433 | let mergedMessages = []; | ||
| 434 | messages.forEach((message) => { | ||
| 435 | if (mergedMessages.length > 0 && mergedMessages[mergedMessages.length - 1].role === message.role) { | ||
| 436 | mergedMessages[mergedMessages.length - 1].content += '\n\n' + message.content; | ||
| 437 | } else { | ||
| 438 | mergedMessages.push(message); | ||
| 439 | } | ||
| 440 | }); | ||
| 441 | |||
| 442 | return mergedMessages; | ||
| 443 | } | ||
| 444 | |||
| 445 | /** | ||
| 371 | * Convert a prompt from the ChatML objects to the format used by MistralAI. | 446 | * Convert a prompt from the ChatML objects to the format used by MistralAI. |
| 372 | * @param {object[]} messages Array of messages | 447 | * @param {object[]} messages Array of messages |
| 373 | * @param {string} charName Character name | 448 | * @param {string} charName Character name |
| @@ -520,4 +595,5 @@ module.exports = { | |||
| 520 | convertCohereMessages, | 595 | convertCohereMessages, |
| 521 | convertMistralMessages, | 596 | convertMistralMessages, |
| 522 | convertCohereTools, | 597 | convertCohereTools, |
| 598 | convertAI21Messages, | ||
| 523 | }; | 599 | }; |
Binary file
| @@ -35,7 +35,7 @@ const tasks = { | |||
| 35 | defaultModel: 'Cohee/fooocus_expansion-onnx', | 35 | defaultModel: 'Cohee/fooocus_expansion-onnx', |
| 36 | pipeline: null, | 36 | pipeline: null, |
| 37 | configField: 'extras.promptExpansionModel', | 37 | configField: 'extras.promptExpansionModel', |
| 38 | quantized: true, | 38 | quantized: false, |
| 39 | }, | 39 | }, |
| 40 | 'automatic-speech-recognition': { | 40 | 'automatic-speech-recognition': { |
| 41 | defaultModel: 'Xenova/whisper-small', | 41 | defaultModel: 'Xenova/whisper-small', |
| @@ -34,8 +34,9 @@ function getConfig() { | |||
| 34 | CACHED_CONFIG = config; | 34 | CACHED_CONFIG = config; |
| 35 | return config; | 35 | return config; |
| 36 | } catch (error) { | 36 | } catch (error) { |
| 37 | console.warn('Failed to read config.yaml'); | 37 | console.error(color.red('FATAL: Failed to read config.yaml. Please check the file for syntax errors.')); |
| 38 | return {}; | 38 | console.error(error.message); |
| 39 | process.exit(1); | ||
| 39 | } | 40 | } |
| 40 | } | 41 | } |
| 41 | 42 | ||
| @@ -298,8 +299,8 @@ const color = { | |||
| 298 | * @returns {string} A UUIDv4 string | 299 | * @returns {string} A UUIDv4 string |
| 299 | */ | 300 | */ |
| 300 | function uuidv4() { | 301 | function uuidv4() { |
| 301 | if ('randomUUID' in crypto) { | 302 | if ('crypto' in global && 'randomUUID' in global.crypto) { |
| 302 | return crypto.randomUUID(); | 303 | return global.crypto.randomUUID(); |
| 303 | } | 304 | } |
| 304 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { | 305 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { |
| 305 | const r = Math.random() * 16 | 0; | 306 | const r = Math.random() * 16 | 0; |
| @@ -23,8 +23,8 @@ async function getMakerSuiteVector(text, directories) { | |||
| 23 | const key = readSecret(directories, SECRET_KEYS.MAKERSUITE); | 23 | const key = readSecret(directories, SECRET_KEYS.MAKERSUITE); |
| 24 | 24 | ||
| 25 | if (!key) { | 25 | if (!key) { |
| 26 | console.log('No MakerSuite key found'); | 26 | console.log('No Google AI Studio key found'); |
| 27 | throw new Error('No MakerSuite key found'); | 27 | throw new Error('No Google AI Studio key found'); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/embedding-gecko-001:embedText?key=${key}`, { | 30 | const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/embedding-gecko-001:embedText?key=${key}`, { |
| @@ -39,8 +39,8 @@ async function getMakerSuiteVector(text, directories) { | |||
| 39 | 39 | ||
| 40 | if (!response.ok) { | 40 | if (!response.ok) { |
| 41 | const text = await response.text(); | 41 | const text = await response.text(); |
| 42 | console.log('MakerSuite request failed', response.statusText, text); | 42 | console.log('Google AI Studio request failed', response.statusText, text); |
| 43 | throw new Error('MakerSuite request failed'); | 43 | throw new Error('Google AI Studio request failed'); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | const data = await response.json(); | 46 | const data = await response.json(); |
| @@ -4513,10 +4513,9 @@ | |||
| 4513 | } | 4513 | } |
| 4514 | }, | 4514 | }, |
| 4515 | "node_modules/micromatch": { | 4515 | "node_modules/micromatch": { |
| 4516 | "version": "4.0.7", | 4516 | "version": "4.0.8", |
| 4517 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", | 4517 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", |
| 4518 | "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", | 4518 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", |
| 4519 | "license": "MIT", | ||
| 4520 | "dependencies": { | 4519 | "dependencies": { |
| 4521 | "braces": "^3.0.3", | 4520 | "braces": "^3.0.3", |
| 4522 | "picomatch": "^2.3.1" | 4521 | "picomatch": "^2.3.1" |