Merge branch 'staging' into pr/Cohee1207/2711
| @@ -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, |
| @@ -196,7 +196,15 @@ | |||
| 196 | "enableLabMode": false, | 196 | "enableLabMode": false, |
| 197 | "enableZenSliders": false, | 197 | "enableZenSliders": false, |
| 198 | "ui_mode": 1, | 198 | "ui_mode": 1, |
| 199 | "forbid_external_media": true | 199 | "forbid_external_media": true, |
| 200 | "stscript": { | ||
| 201 | "parser": { | ||
| 202 | "flags": { | ||
| 203 | "1": true, | ||
| 204 | "2": true | ||
| 205 | } | ||
| 206 | } | ||
| 207 | } | ||
| 200 | }, | 208 | }, |
| 201 | "extension_settings": { | 209 | "extension_settings": { |
| 202 | "apiUrl": "http://localhost:5100", | 210 | "apiUrl": "http://localhost:5100", |
| @@ -452,7 +460,6 @@ | |||
| 452 | "temp_openai": 1.0, | 460 | "temp_openai": 1.0, |
| 453 | "freq_pen_openai": 0, | 461 | "freq_pen_openai": 0, |
| 454 | "pres_pen_openai": 0, | 462 | "pres_pen_openai": 0, |
| 455 | "count_pen": 0, | ||
| 456 | "top_p_openai": 1, | 463 | "top_p_openai": 1, |
| 457 | "top_k_openai": 0, | 464 | "top_k_openai": 0, |
| 458 | "stream_openai": true, | 465 | "stream_openai": true, |
| @@ -614,7 +621,7 @@ | |||
| 614 | "wi_format": "{0}", | 621 | "wi_format": "{0}", |
| 615 | "openai_model": "gpt-4-turbo", | 622 | "openai_model": "gpt-4-turbo", |
| 616 | "claude_model": "claude-3-5-sonnet-20240620", | 623 | "claude_model": "claude-3-5-sonnet-20240620", |
| 617 | "ai21_model": "j2-ultra", | 624 | "ai21_model": "jamba-1.5-large", |
| 618 | "windowai_model": "", | 625 | "windowai_model": "", |
| 619 | "openrouter_model": "OR_Website", | 626 | "openrouter_model": "OR_Website", |
| 620 | "jailbreak_system": true, | 627 | "jailbreak_system": true, |
| @@ -625,7 +632,6 @@ | |||
| 625 | "show_external_models": false, | 632 | "show_external_models": false, |
| 626 | "proxy_password": "", | 633 | "proxy_password": "", |
| 627 | "assistant_prefill": "", | 634 | "assistant_prefill": "", |
| 628 | "assistant_impersonation": "", | 635 | "assistant_impersonation": "" |
| 629 | "use_ai21_tokenizer": false | ||
| 630 | } | 636 | } |
| 631 | } | 637 | } |
| @@ -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> |
| @@ -1291,6 +1278,28 @@ | |||
| 1291 | </div> | 1278 | </div> |
| 1292 | </div> | 1279 | </div> |
| 1293 | </div> | 1280 | </div> |
| 1281 | |||
| 1282 | <div data-newbie-hidden data-tg-type="koboldcpp" id="xtc_block" class="wide100p"> | ||
| 1283 | <h4 class="wide100p textAlignCenter"> | ||
| 1284 | <label data-i18n="Exclude Top Choices (XTC)">Exclude Top Choices (XTC)</label> | ||
| 1285 | <a href="https://github.com/oobabooga/text-generation-webui/pull/6335" target="_blank"> | ||
| 1286 | <div class=" fa-solid fa-circle-info opacity50p"></div> | ||
| 1287 | </a> | ||
| 1288 | </h4> | ||
| 1289 | <div class="flex-container flexFlowRow gap10px flexShrink"> | ||
| 1290 | <div class="alignitemscenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0"> | ||
| 1291 | <small data-i18n="Threshold">Threshold</small> | ||
| 1292 | <input class="neo-range-slider" type="range" id="xtc_threshold_textgenerationwebui" name="volume" min="0" max="0.5" step="0.01" /> | ||
| 1293 | <input class="neo-range-input" type="number" min="0" max="0.5" step="0.01" data-for="xtc_threshold_textgenerationwebui" id="xtc_threshold_counter_textgenerationwebui"> | ||
| 1294 | </div> | ||
| 1295 | <div class="alignitemscenter flex-container flexFlowColumn flexBasis48p flexGrow flexShrink gap0"> | ||
| 1296 | <small data-i18n="Probability">Probability</small> | ||
| 1297 | <input class="neo-range-slider" type="range" id="xtc_probability_textgenerationwebui" name="volume" min="0" max="1" step="0.01" /> | ||
| 1298 | <input class="neo-range-input" type="number" min="0" max="1" step="0.01" data-for="xtc_probability_textgenerationwebui" id="xtc_probability_counter_textgenerationwebui"> | ||
| 1299 | </div> | ||
| 1300 | </div> | ||
| 1301 | </div> | ||
| 1302 | |||
| 1294 | <!-- Enable for llama.cpp when the PR is merged: https://github.com/ggerganov/llama.cpp/pull/6839 --> | 1303 | <!-- Enable for llama.cpp when the PR is merged: https://github.com/ggerganov/llama.cpp/pull/6839 --> |
| 1295 | <div data-newbie-hidden data-tg-type="ooba, koboldcpp" id="dryBlock" class="wide100p"> | 1304 | <div data-newbie-hidden data-tg-type="ooba, koboldcpp" id="dryBlock" class="wide100p"> |
| 1296 | <h4 class="wide100p textAlignCenter" title="DRY penalizes tokens that would extend the end of the input into a sequence that has previously occurred in the input. Set multiplier to 0 to disable." data-i18n="[title]DRY_Repetition_Penalty_desc"> | 1305 | <h4 class="wide100p textAlignCenter" title="DRY penalizes tokens that would extend the end of the input into a sequence that has previously occurred in the input. Set multiplier to 0 to disable." data-i18n="[title]DRY_Repetition_Penalty_desc"> |
| @@ -1484,11 +1493,11 @@ | |||
| 1484 | <div id="banned_tokens_block_ooba" data-newbie-hidden class="wide100p"> | 1493 | <div id="banned_tokens_block_ooba" data-newbie-hidden class="wide100p"> |
| 1485 | <hr data-newbie-hidden class="width100p"> | 1494 | <hr data-newbie-hidden class="width100p"> |
| 1486 | <h4 class="range-block-title justifyCenter"> | 1495 | <h4 class="range-block-title justifyCenter"> |
| 1487 | <span data-i18n="Banned Tokens">Banned Tokens</span> | 1496 | <span data-i18n="Banned Tokens">Banned Tokens/Strings</span> |
| 1488 | <div class="margin5 fa-solid fa-circle-info opacity50p " data-i18n="[title]LLaMA / Mistral / Yi models only" title="LLaMA / Mistral / Yi models only. Make sure to select an appropriate tokenizer first. Sequences you don't want to appear in the output. One per line. Text or [token ids]. Most tokens have a leading space. Use token counter if unsure."></div> | 1497 | <div class="margin5 fa-solid fa-circle-info opacity50p " data-i18n="[title]LLaMA / Mistral / Yi models only" title="Enter sequences you don't want to appear in the output. Unquoted text will be tokenized in the back end and banned as tokens. [token ids] will be banned as-is. Most tokens have a leading space. Use token counter (with the correct tokenizer selected first!) if you are unsure. Enclose text in double quotes to ban the entire string as a set. Quoted Strings and [Token ids] must be on their own line."></div> |
| 1489 | </h4> | 1498 | </h4> |
| 1490 | <div class="wide100p"> | 1499 | <div class="wide100p"> |
| 1491 | <textarea id="banned_tokens_textgenerationwebui" class="text_pole textarea_compact" name="banned_tokens_textgenerationwebui" rows="3" data-i18n="[placeholder]Example: some text [42, 69, 1337]" placeholder="Example: some text [42, 69, 1337]"></textarea> | 1500 | <textarea id="banned_tokens_textgenerationwebui" class="text_pole textarea_compact" name="banned_tokens_textgenerationwebui" rows="3" data-i18n="[placeholder]Example: some text [42, 69, 1337]" placeholder='some text as tokens [420, 69, 1337] "Some verbatim string"'></textarea> |
| 1492 | </div> | 1501 | </div> |
| 1493 | </div> | 1502 | </div> |
| 1494 | <div class="range-block wide100p"> | 1503 | <div class="range-block wide100p"> |
| @@ -1791,22 +1800,6 @@ | |||
| 1791 | </select> | 1800 | </select> |
| 1792 | </div> | 1801 | </div> |
| 1793 | </div> | 1802 | </div> |
| 1794 | <div class="range-block" data-source="ai21"> | ||
| 1795 | <label for="use_ai21_tokenizer" title="Use AI21 Tokenizer" data-i18n="[title]Use AI21 Tokenizer" class="checkbox_label widthFreeExpand"> | ||
| 1796 | <input id="use_ai21_tokenizer" type="checkbox" /><span data-i18n="Use AI21 Tokenizer">Use AI21 Tokenizer</span> | ||
| 1797 | </label> | ||
| 1798 | <div class="toggle-description justifyLeft"> | ||
| 1799 | <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> | ||
| 1800 | </div> | ||
| 1801 | </div> | ||
| 1802 | <div class="range-block" data-source="makersuite"> | ||
| 1803 | <label for="use_google_tokenizer" title="Use Google Tokenizer" data-i18n="[title]Use Google Tokenizer" class="checkbox_label widthFreeExpand"> | ||
| 1804 | <input id="use_google_tokenizer" type="checkbox" /><span data-i18n="Use Google Tokenizer">Use Google Tokenizer</span> | ||
| 1805 | </label> | ||
| 1806 | <div class="toggle-description justifyLeft"> | ||
| 1807 | <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> | ||
| 1808 | </div> | ||
| 1809 | </div> | ||
| 1810 | <div class="range-block" data-source="makersuite"> | 1803 | <div class="range-block" data-source="makersuite"> |
| 1811 | <label for="use_makersuite_sysprompt" class="checkbox_label widthFreeExpand"> | 1804 | <label for="use_makersuite_sysprompt" class="checkbox_label widthFreeExpand"> |
| 1812 | <input id="use_makersuite_sysprompt" type="checkbox" /> | 1805 | <input id="use_makersuite_sysprompt" type="checkbox" /> |
| @@ -1852,7 +1845,7 @@ | |||
| 1852 | <div class="fa-solid fa-clock-rotate-left"></div> | 1845 | <div class="fa-solid fa-clock-rotate-left"></div> |
| 1853 | </div> | 1846 | </div> |
| 1854 | </div> | 1847 | </div> |
| 1855 | <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> | 1848 | <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> |
| 1856 | </div> | 1849 | </div> |
| 1857 | </div> | 1850 | </div> |
| 1858 | </div> | 1851 | </div> |
| @@ -2791,10 +2784,12 @@ | |||
| 2791 | <div> | 2784 | <div> |
| 2792 | <h4 data-i18n="AI21 Model">AI21 Model</h4> | 2785 | <h4 data-i18n="AI21 Model">AI21 Model</h4> |
| 2793 | <select id="model_ai21_select"> | 2786 | <select id="model_ai21_select"> |
| 2794 | <optgroup label="Latest"> | 2787 | <optgroup label="Jamba 1.5"> |
| 2795 | <option value="j2-ultra">j2-ultra</option> | 2788 | <option value="jamba-1.5-mini">jamba-1.5-mini</option> |
| 2796 | <option value="j2-mid">j2-mid</option> | 2789 | <option value="jamba-1.5-large">jamba-1.5-large</option> |
| 2797 | <option value="j2-light">j2-light</option> | 2790 | </optgroup> |
| 2791 | <optgroup label="Jamba-Instruct (Deprecated)"> | ||
| 2792 | <option value="jamba-instruct-preview">jamba-instruct-preview</option> | ||
| 2798 | </optgroup> | 2793 | </optgroup> |
| 2799 | </select> | 2794 | </select> |
| 2800 | </div> | 2795 | </div> |
| @@ -2824,8 +2819,11 @@ | |||
| 2824 | </optgroup> | 2819 | </optgroup> |
| 2825 | <optgroup label="Subversions"> | 2820 | <optgroup label="Subversions"> |
| 2826 | <option value="gemini-1.5-pro-exp-0801">Gemini 1.5 Pro Experiment 2024-08-01</option> | 2821 | <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-0827">Gemini 1.5 Pro Experiment 2024-08-27</option> | ||
| 2827 | <option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option> | 2823 | <option value="gemini-1.5-pro-latest">Gemini 1.5 Pro [latest]</option> |
| 2828 | <option value="gemini-1.5-pro-001">Gemini 1.5 Pro [001]</option> | 2824 | <option value="gemini-1.5-pro-001">Gemini 1.5 Pro [001]</option> |
| 2825 | <option value="gemini-1.5-flash-exp-0827">Gemini 1.5 Flash Experiment 2024-08-27</option> | ||
| 2826 | <option value="gemini-1.5-flash-8b-exp-0827">Gemini 1.5 Flash 8B Experiment 2024-08-27</option> | ||
| 2829 | <option value="gemini-1.5-flash-latest">Gemini 1.5 Flash [latest]</option> | 2827 | <option value="gemini-1.5-flash-latest">Gemini 1.5 Flash [latest]</option> |
| 2830 | <option value="gemini-1.5-flash-001">Gemini 1.5 Flash [001]</option> | 2828 | <option value="gemini-1.5-flash-001">Gemini 1.5 Flash [001]</option> |
| 2831 | <option value="gemini-1.0-pro-latest">Gemini 1.0 Pro [latest]</option> | 2829 | <option value="gemini-1.0-pro-latest">Gemini 1.0 Pro [latest]</option> |
| @@ -2955,6 +2953,8 @@ | |||
| 2955 | <option value="command">command</option> | 2953 | <option value="command">command</option> |
| 2956 | <option value="command-r">command-r</option> | 2954 | <option value="command-r">command-r</option> |
| 2957 | <option value="command-r-plus">command-r-plus</option> | 2955 | <option value="command-r-plus">command-r-plus</option> |
| 2956 | <option value="command-r-08-2024">command-r-08-2024</option> | ||
| 2957 | <option value="command-r-plus-08-2024">command-r-plus-08-2024</option> | ||
| 2958 | </optgroup> | 2958 | </optgroup> |
| 2959 | <optgroup label="Nightly"> | 2959 | <optgroup label="Nightly"> |
| 2960 | <option value="command-light-nightly">command-light-nightly</option> | 2960 | <option value="command-light-nightly">command-light-nightly</option> |
| @@ -4012,7 +4012,7 @@ | |||
| 4012 | <input id="movingUImode" type="checkbox" /> | 4012 | <input id="movingUImode" type="checkbox" /> |
| 4013 | <small data-i18n="Movable UI Panels">MovingUI <i class="fa-solid fa-desktop"></i></small> | 4013 | <small data-i18n="Movable UI Panels">MovingUI <i class="fa-solid fa-desktop"></i></small> |
| 4014 | </label> | 4014 | </label> |
| 4015 | <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> | 4015 | <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> |
| 4016 | </div> | 4016 | </div> |
| 4017 | <div data-newbie-hidden id="MovingUI-presets-block" class="flex-container alignitemscenter"> | 4017 | <div data-newbie-hidden id="MovingUI-presets-block" class="flex-container alignitemscenter"> |
| 4018 | <div class="flex-container alignItemsFlexEnd"> | 4018 | <div class="flex-container alignItemsFlexEnd"> |
| @@ -4503,6 +4503,7 @@ | |||
| 4503 | <div data-newbie-hidden> | 4503 | <div data-newbie-hidden> |
| 4504 | <label for="persona_description_position" data-i18n="Position:">Position:</label> | 4504 | <label for="persona_description_position" data-i18n="Position:">Position:</label> |
| 4505 | <select id="persona_description_position"> | 4505 | <select id="persona_description_position"> |
| 4506 | <option value="9" data-i18n="None (disabled)">None (disabled)</option> | ||
| 4506 | <option value="0" data-i18n="In Story String / Prompt Manager">In Story String / Prompt Manager</option> | 4507 | <option value="0" data-i18n="In Story String / Prompt Manager">In Story String / Prompt Manager</option> |
| 4507 | <option value="2" data-i18n="Top of Author's Note">Top of Author's Note</option> | 4508 | <option value="2" data-i18n="Top of Author's Note">Top of Author's Note</option> |
| 4508 | <option value="3" data-i18n="Bottom of Author's Note">Bottom of Author's Note</option> | 4509 | <option value="3" data-i18n="Bottom of Author's Note">Bottom of Author's Note</option> |
| @@ -6488,6 +6489,7 @@ | |||
| 6488 | <script src="lib/jquery-cookie-1.4.1.min.js"></script> | 6489 | <script src="lib/jquery-cookie-1.4.1.min.js"></script> |
| 6489 | <script src="lib/jquery.ui.touch-punch.min.js"></script> | 6490 | <script src="lib/jquery.ui.touch-punch.min.js"></script> |
| 6490 | <script src="lib/showdown.min.js"></script> | 6491 | <script src="lib/showdown.min.js"></script> |
| 6492 | <script src="lib/showdown-patch.js"></script> | ||
| 6491 | <script src="lib/showdown-katex.min.js"></script> | 6493 | <script src="lib/showdown-katex.min.js"></script> |
| 6492 | <script src="lib/popper.js"></script> | 6494 | <script src="lib/popper.js"></script> |
| 6493 | <script src="lib/purify.min.js"></script> | 6495 | <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 | }); | ||
| @@ -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": "Вставить файл или изображение", |
| @@ -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 | } |
| @@ -488,14 +488,6 @@ let default_user_name = 'User'; | |||
| 488 | export let name1 = default_user_name; | 488 | export let name1 = default_user_name; |
| 489 | export let name2 = 'SillyTavern System'; | 489 | export let name2 = 'SillyTavern System'; |
| 490 | export let chat = []; | 490 | export let chat = []; |
| 491 | let safetychat = [ | ||
| 492 | { | ||
| 493 | name: systemUserName, | ||
| 494 | is_user: false, | ||
| 495 | create_date: 0, | ||
| 496 | mes: 'You deleted a character/chat and arrived back here for safety reasons! Pick another character!', | ||
| 497 | }, | ||
| 498 | ]; | ||
| 499 | let chatSaveTimeout; | 491 | let chatSaveTimeout; |
| 500 | let importFlashTimeout; | 492 | let importFlashTimeout; |
| 501 | export let isChatSaving = false; | 493 | export let isChatSaving = false; |
| @@ -594,6 +586,17 @@ export const extension_prompt_roles = { | |||
| 594 | 586 | ||
| 595 | export const MAX_INJECTION_DEPTH = 1000; | 587 | export const MAX_INJECTION_DEPTH = 1000; |
| 596 | 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 | |||
| 597 | export let system_messages = {}; | 600 | export let system_messages = {}; |
| 598 | 601 | ||
| 599 | async function getSystemMessages() { | 602 | async function getSystemMessages() { |
| @@ -2192,7 +2195,7 @@ export function addCopyToCodeBlocks(messageElement) { | |||
| 2192 | codeBlocks.get(i).appendChild(copyButton); | 2195 | codeBlocks.get(i).appendChild(copyButton); |
| 2193 | copyButton.addEventListener('pointerup', function (event) { | 2196 | copyButton.addEventListener('pointerup', function (event) { |
| 2194 | navigator.clipboard.writeText(codeBlocks.get(i).innerText); | 2197 | navigator.clipboard.writeText(codeBlocks.get(i).innerText); |
| 2195 | toastr.info('Copied!', '', { timeOut: 2000 }); | 2198 | toastr.info(t`Copied!`, '', { timeOut: 2000 }); |
| 2196 | }); | 2199 | }); |
| 2197 | } | 2200 | } |
| 2198 | } | 2201 | } |
| @@ -2705,7 +2708,7 @@ function addPersonaDescriptionExtensionPrompt() { | |||
| 2705 | const INJECT_TAG = 'PERSONA_DESCRIPTION'; | 2708 | const INJECT_TAG = 'PERSONA_DESCRIPTION'; |
| 2706 | setExtensionPrompt(INJECT_TAG, '', extension_prompt_types.IN_PROMPT, 0); | 2709 | setExtensionPrompt(INJECT_TAG, '', extension_prompt_types.IN_PROMPT, 0); |
| 2707 | 2710 | ||
| 2708 | if (!power_user.persona_description) { | 2711 | if (!power_user.persona_description || power_user.persona_description_position === persona_description_positions.NONE) { |
| 2709 | return; | 2712 | return; |
| 2710 | } | 2713 | } |
| 2711 | 2714 | ||
| @@ -2826,7 +2829,7 @@ export function getCharacterCardFields() { | |||
| 2826 | } | 2829 | } |
| 2827 | 2830 | ||
| 2828 | export function isStreamingEnabled() { | 2831 | export function isStreamingEnabled() { |
| 2829 | const noStreamSources = [chat_completion_sources.SCALE, chat_completion_sources.AI21]; | 2832 | const noStreamSources = [chat_completion_sources.SCALE]; |
| 2830 | 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'))) |
| 2831 | || (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) |
| 2832 | || (main_api == 'novel' && nai_settings.streaming_novel) | 2835 | || (main_api == 'novel' && nai_settings.streaming_novel) |
| @@ -3726,7 +3729,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3726 | const storyStringParams = { | 3729 | const storyStringParams = { |
| 3727 | description: description, | 3730 | description: description, |
| 3728 | personality: personality, | 3731 | personality: personality, |
| 3729 | persona: persona, | 3732 | persona: power_user.persona_description_position == persona_description_positions.IN_PROMPT ? persona : '', |
| 3730 | scenario: scenario, | 3733 | scenario: scenario, |
| 3731 | system: isInstruct ? system : '', | 3734 | system: isInstruct ? system : '', |
| 3732 | char: name2, | 3735 | char: name2, |
| @@ -3760,7 +3763,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3760 | } | 3763 | } |
| 3761 | 3764 | ||
| 3762 | let examplesString = ''; | 3765 | let examplesString = ''; |
| 3763 | let chatString = ''; | 3766 | let chatString = addChatsPreamble(addChatsSeparator('')); |
| 3764 | let cyclePrompt = ''; | 3767 | let cyclePrompt = ''; |
| 3765 | 3768 | ||
| 3766 | async function getMessagesTokenCount() { | 3769 | async function getMessagesTokenCount() { |
| @@ -3769,10 +3772,10 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3769 | storyString, | 3772 | storyString, |
| 3770 | afterScenarioAnchor, | 3773 | afterScenarioAnchor, |
| 3771 | examplesString, | 3774 | examplesString, |
| 3775 | userAlignmentMessage, | ||
| 3772 | chatString, | 3776 | chatString, |
| 3773 | quiet_prompt, | 3777 | modifyLastPromptLine(''), |
| 3774 | cyclePrompt, | 3778 | cyclePrompt, |
| 3775 | userAlignmentMessage, | ||
| 3776 | ].join('').replace(/\r/gm, ''); | 3779 | ].join('').replace(/\r/gm, ''); |
| 3777 | return getTokenCountAsync(encodeString, power_user.token_padding); | 3780 | return getTokenCountAsync(encodeString, power_user.token_padding); |
| 3778 | } | 3781 | } |
| @@ -3803,8 +3806,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3803 | } | 3806 | } |
| 3804 | 3807 | ||
| 3805 | tokenCount += await getTokenCountAsync(item.replace(/\r/gm, '')); | 3808 | tokenCount += await getTokenCountAsync(item.replace(/\r/gm, '')); |
| 3806 | chatString = item + chatString; | ||
| 3807 | if (tokenCount < this_max_context) { | 3809 | if (tokenCount < this_max_context) { |
| 3810 | chatString = chatString + item; | ||
| 3808 | arrMes[index] = item; | 3811 | arrMes[index] = item; |
| 3809 | lastAddedIndex = Math.max(lastAddedIndex, index); | 3812 | lastAddedIndex = Math.max(lastAddedIndex, index); |
| 3810 | } else { | 3813 | } else { |
| @@ -3830,8 +3833,8 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 3830 | } | 3833 | } |
| 3831 | 3834 | ||
| 3832 | tokenCount += await getTokenCountAsync(item.replace(/\r/gm, '')); | 3835 | tokenCount += await getTokenCountAsync(item.replace(/\r/gm, '')); |
| 3833 | chatString = item + chatString; | ||
| 3834 | if (tokenCount < this_max_context) { | 3836 | if (tokenCount < this_max_context) { |
| 3837 | chatString = chatString + item; | ||
| 3835 | arrMes[i] = item; | 3838 | arrMes[i] = item; |
| 3836 | lastAddedIndex = Math.max(lastAddedIndex, i); | 3839 | lastAddedIndex = Math.max(lastAddedIndex, i); |
| 3837 | } else { | 3840 | } else { |
| @@ -4028,15 +4031,16 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4028 | async function checkPromptSize() { | 4031 | async function checkPromptSize() { |
| 4029 | console.debug('---checking Prompt size'); | 4032 | console.debug('---checking Prompt size'); |
| 4030 | setPromptString(); | 4033 | setPromptString(); |
| 4034 | const jointMessages = mesSend.map((e) => `${e.extensionPrompts.join('')}${e.message}`).join(''); | ||
| 4031 | const prompt = [ | 4035 | const prompt = [ |
| 4032 | beforeScenarioAnchor, | 4036 | beforeScenarioAnchor, |
| 4033 | storyString, | 4037 | storyString, |
| 4034 | afterScenarioAnchor, | 4038 | afterScenarioAnchor, |
| 4035 | mesExmString, | 4039 | mesExmString, |
| 4036 | mesSend.map((e) => `${e.extensionPrompts.join('')}${e.message}`).join(''), | 4040 | addChatsPreamble(addChatsSeparator(jointMessages)), |
| 4037 | '\n', | 4041 | '\n', |
| 4042 | modifyLastPromptLine(''), | ||
| 4038 | generatedPromptCache, | 4043 | generatedPromptCache, |
| 4039 | quiet_prompt, | ||
| 4040 | ].join('').replace(/\r/gm, ''); | 4044 | ].join('').replace(/\r/gm, ''); |
| 4041 | let thisPromptContextSize = await getTokenCountAsync(prompt, power_user.token_padding); | 4045 | let thisPromptContextSize = await getTokenCountAsync(prompt, power_user.token_padding); |
| 4042 | 4046 | ||
| @@ -4302,7 +4306,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro | |||
| 4302 | padding: power_user.token_padding, | 4306 | padding: power_user.token_padding, |
| 4303 | main_api: main_api, | 4307 | main_api: main_api, |
| 4304 | 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) : '', |
| 4305 | userPersona: (power_user.persona_description || ''), | 4309 | userPersona: (power_user.persona_description_position == persona_description_positions.IN_PROMPT ? (persona || '') : ''), |
| 4306 | }; | 4310 | }; |
| 4307 | 4311 | ||
| 4308 | //console.log(additionalPromptStuff); | 4312 | //console.log(additionalPromptStuff); |
| @@ -5080,7 +5084,7 @@ async function promptItemize(itemizedPrompts, requestedMesId) { | |||
| 5080 | } | 5084 | } |
| 5081 | 5085 | ||
| 5082 | navigator.clipboard.writeText(rawPromptValues); | 5086 | navigator.clipboard.writeText(rawPromptValues); |
| 5083 | toastr.info('Copied!'); | 5087 | toastr.info(t`Copied!`); |
| 5084 | }); | 5088 | }); |
| 5085 | 5089 | ||
| 5086 | popup.dlg.querySelector('#showRawPrompt').addEventListener('click', function () { | 5090 | popup.dlg.querySelector('#showRawPrompt').addEventListener('click', function () { |
| @@ -5679,7 +5683,7 @@ export function resetChatState() { | |||
| 5679 | // 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. |
| 5680 | name2 = systemUserName; | 5684 | name2 = systemUserName; |
| 5681 | // 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 |
| 5682 | chat = [...safetychat]; | 5686 | chat.splice(0, chat.length, ...SAFETY_CHAT); |
| 5683 | // resets chat metadata | 5687 | // resets chat metadata |
| 5684 | chat_metadata = {}; | 5688 | chat_metadata = {}; |
| 5685 | // resets the characters array, forcing getcharacters to reset | 5689 | // resets the characters array, forcing getcharacters to reset |
| @@ -6310,7 +6314,7 @@ export function setUserName(value) { | |||
| 6310 | console.log(`User name changed to ${name1}`); | 6314 | console.log(`User name changed to ${name1}`); |
| 6311 | $('#your_name').val(name1); | 6315 | $('#your_name').val(name1); |
| 6312 | if (power_user.persona_show_notifications) { | 6316 | if (power_user.persona_show_notifications) { |
| 6313 | 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`); |
| 6314 | } | 6318 | } |
| 6315 | saveSettingsDebounced(); | 6319 | saveSettingsDebounced(); |
| 6316 | } | 6320 | } |
| @@ -8840,16 +8844,21 @@ export async function handleDeleteCharacter(this_chid, delete_chats) { | |||
| 8840 | /** | 8844 | /** |
| 8841 | * Deletes a character completely, including associated chats if specified | 8845 | * Deletes a character completely, including associated chats if specified |
| 8842 | * | 8846 | * |
| 8843 | * @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 |
| 8844 | * @param {Object} [options] - Optional parameters for the deletion | 8848 | * @param {Object} [options] - Optional parameters for the deletion |
| 8845 | * @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 |
| 8846 | * @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 |
| 8847 | */ | 8851 | */ |
| 8848 | export async function deleteCharacter(characterKey, { deleteChats = true } = {}) { | 8852 | export async function deleteCharacter(characterKey, { deleteChats = true } = {}) { |
| 8849 | 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); | ||
| 8850 | if (!character) { | 8859 | if (!character) { |
| 8851 | toastr.warning(`Character ${characterKey} not found. Cannot be deleted.`); | 8860 | toastr.warning(`Character ${key} not found. Skipping deletion.`); |
| 8852 | return; | 8861 | continue; |
| 8853 | } | 8862 | } |
| 8854 | 8863 | ||
| 8855 | const chid = characters.indexOf(character); | 8864 | const chid = characters.indexOf(character); |
| @@ -8865,10 +8874,12 @@ export async function deleteCharacter(characterKey, { deleteChats = true } = {}) | |||
| 8865 | }); | 8874 | }); |
| 8866 | 8875 | ||
| 8867 | if (!response.ok) { | 8876 | if (!response.ok) { |
| 8868 | throw new Error(`Failed to delete character: ${response.status} ${response.statusText}`); | 8877 | toastr.error(`${response.status} ${response.statusText}`, 'Failed to delete character'); |
| 8878 | continue; | ||
| 8869 | } | 8879 | } |
| 8870 | 8880 | ||
| 8871 | await removeCharacterFromUI(character.name, character.avatar); | 8881 | delete tag_map[character.avatar]; |
| 8882 | select_rm_info('char_delete', character.name); | ||
| 8872 | 8883 | ||
| 8873 | if (deleteChats) { | 8884 | if (deleteChats) { |
| 8874 | for (const chat of pastChats) { | 8885 | for (const chat of pastChats) { |
| @@ -8877,35 +8888,30 @@ export async function deleteCharacter(characterKey, { deleteChats = true } = {}) | |||
| 8877 | } | 8888 | } |
| 8878 | } | 8889 | } |
| 8879 | 8890 | ||
| 8880 | 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(); | ||
| 8881 | } | 8895 | } |
| 8882 | 8896 | ||
| 8883 | /** | 8897 | /** |
| 8884 | * 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. |
| 8885 | * 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 |
| 8886 | * 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 |
| 8887 | * 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. |
| 8888 | * avatar from tag_map, fetching updated list of characters and updating the 'deleted | ||
| 8889 | * character' message. | ||
| 8890 | * It also ensures to save the settings after all the operations. | 8902 | * It also ensures to save the settings after all the operations. |
| 8891 | * | ||
| 8892 | * @param {string} name - The name of the character to be deleted. | ||
| 8893 | * @param {string} avatar - The avatar URL of the character to be deleted. | ||
| 8894 | * @param {boolean} reloadCharacters - Whether the character list should be refreshed after deletion. | ||
| 8895 | */ | 8903 | */ |
| 8896 | async function removeCharacterFromUI(name, avatar, reloadCharacters = true) { | 8904 | async function removeCharacterFromUI() { |
| 8897 | await clearChat(); | 8905 | await clearChat(); |
| 8898 | $('#character_cross').click(); | 8906 | $('#character_cross').click(); |
| 8899 | this_chid = undefined; | 8907 | this_chid = undefined; |
| 8900 | characters.length = 0; | 8908 | characters.length = 0; |
| 8901 | name2 = systemUserName; | 8909 | name2 = systemUserName; |
| 8902 | chat = [...safetychat]; | 8910 | chat.splice(0, chat.length, ...SAFETY_CHAT); |
| 8903 | chat_metadata = {}; | 8911 | chat_metadata = {}; |
| 8904 | $(document.getElementById('rm_button_selected_ch')).children('h2').text(''); | 8912 | $(document.getElementById('rm_button_selected_ch')).children('h2').text(''); |
| 8905 | this_chid = undefined; | 8913 | this_chid = undefined; |
| 8906 | delete tag_map[avatar]; | 8914 | await getCharacters(); |
| 8907 | if (reloadCharacters) await getCharacters(); | ||
| 8908 | select_rm_info('char_delete', name); | ||
| 8909 | await printMessages(); | 8915 | await printMessages(); |
| 8910 | saveSettingsDebounced(); | 8916 | saveSettingsDebounced(); |
| 8911 | } | 8917 | } |
| @@ -9532,11 +9538,7 @@ jQuery(async function () { | |||
| 9532 | 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(); |
| 9533 | const oldFileName = oldFileNameFull.replace('.jsonl', ''); | 9539 | const oldFileName = oldFileNameFull.replace('.jsonl', ''); |
| 9534 | 9540 | ||
| 9535 | const popupText = `<h3>Enter the new name for the chat:<h3> | 9541 | const popupText = await renderTemplateAsync('chatRename'); |
| 9536 | <small>!!Using an existing filename will produce an error!!<br> | ||
| 9537 | This will break the link between checkpoint chats.<br> | ||
| 9538 | No need to add '.jsonl' at the end.<br> | ||
| 9539 | </small>`; | ||
| 9540 | const newName = await callPopup(popupText, 'input', oldFileName); | 9542 | const newName = await callPopup(popupText, 'input', oldFileName); |
| 9541 | 9543 | ||
| 9542 | if (!newName || newName == oldFileName) { | 9544 | if (!newName || newName == oldFileName) { |
| @@ -9744,12 +9746,7 @@ jQuery(async function () { | |||
| 9744 | else if (id == 'option_start_new_chat') { | 9746 | else if (id == 'option_start_new_chat') { |
| 9745 | if ((selected_group || this_chid !== undefined) && !is_send_press) { | 9747 | if ((selected_group || this_chid !== undefined) && !is_send_press) { |
| 9746 | let deleteCurrentChat = false; | 9748 | let deleteCurrentChat = false; |
| 9747 | const result = await Popup.show.confirm('Start new chat?', ` | 9749 | const result = await Popup.show.confirm(t`Start new chat?`, await renderTemplateAsync('newChatConfirm'), { |
| 9748 | <label for="del_chat_checkbox" class="checkbox_label justifyCenter" | ||
| 9749 | title="If necessary, you can later restore this chat file from the /backups folder"> | ||
| 9750 | <input type="checkbox" id="del_chat_checkbox" /> | ||
| 9751 | <small>Also delete the current chat file</small> | ||
| 9752 | </label>`, { | ||
| 9753 | onClose: () => deleteCurrentChat = !!$('#del_chat_checkbox').prop('checked'), | 9750 | onClose: () => deleteCurrentChat = !!$('#del_chat_checkbox').prop('checked'), |
| 9754 | }); | 9751 | }); |
| 9755 | if (!result) { | 9752 | if (!result) { |
| @@ -10261,10 +10258,10 @@ jQuery(async function () { | |||
| 10261 | 10258 | ||
| 10262 | let deleteOnlySwipe = false; | 10259 | let deleteOnlySwipe = false; |
| 10263 | if (power_user.confirm_message_delete && fromSlashCommand !== true) { | 10260 | if (power_user.confirm_message_delete && fromSlashCommand !== true) { |
| 10264 | 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, { |
| 10265 | okButton: canDeleteSwipe ? 'Delete Swipe' : 'Delete Message', | 10262 | okButton: canDeleteSwipe ? t`Delete Swipe` : t`Delete Message`, |
| 10266 | cancelButton: 'Cancel', | 10263 | cancelButton: 'Cancel', |
| 10267 | customButtons: canDeleteSwipe ? ['Delete Message'] : null, | 10264 | customButtons: canDeleteSwipe ? [t`Delete Message`] : null, |
| 10268 | }); | 10265 | }); |
| 10269 | if (!result) { | 10266 | if (!result) { |
| 10270 | 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 |
| @@ -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> |
| @@ -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); |
| @@ -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(); |
| @@ -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); |
| @@ -107,6 +107,7 @@ export const persona_description_positions = { | |||
| 107 | TOP_AN: 2, | 107 | TOP_AN: 2, |
| 108 | BOTTOM_AN: 3, | 108 | BOTTOM_AN: 3, |
| 109 | AT_DEPTH: 4, | 109 | AT_DEPTH: 4, |
| 110 | NONE: 9, | ||
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 112 | let power_user = { | 113 | let power_user = { |
| @@ -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 | |
| @@ -188,6 +188,8 @@ const settings = { | |||
| 188 | custom_model: '', | 188 | custom_model: '', |
| 189 | bypass_status_check: false, | 189 | bypass_status_check: false, |
| 190 | openrouter_allow_fallbacks: true, | 190 | openrouter_allow_fallbacks: true, |
| 191 | xtc_threshold: 0.1, | ||
| 192 | xtc_probability: 0, | ||
| 191 | }; | 193 | }; |
| 192 | 194 | ||
| 193 | export let textgenerationwebui_banned_in_macros = []; | 195 | export let textgenerationwebui_banned_in_macros = []; |
| @@ -263,6 +265,8 @@ export const setting_names = [ | |||
| 263 | 'custom_model', | 265 | 'custom_model', |
| 264 | 'bypass_status_check', | 266 | 'bypass_status_check', |
| 265 | 'openrouter_allow_fallbacks', | 267 | 'openrouter_allow_fallbacks', |
| 268 | 'xtc_threshold', | ||
| 269 | 'xtc_probability', | ||
| 266 | ]; | 270 | ]; |
| 267 | 271 | ||
| 268 | const DYNATEMP_BLOCK = document.getElementById('dynatemp_block_ooba'); | 272 | const DYNATEMP_BLOCK = document.getElementById('dynatemp_block_ooba'); |
| @@ -718,6 +722,8 @@ jQuery(function () { | |||
| 718 | 'dry_multiplier_textgenerationwebui': 0, | 722 | 'dry_multiplier_textgenerationwebui': 0, |
| 719 | 'dry_base_textgenerationwebui': 1.75, | 723 | 'dry_base_textgenerationwebui': 1.75, |
| 720 | 'dry_penalty_last_n_textgenerationwebui': 0, | 724 | 'dry_penalty_last_n_textgenerationwebui': 0, |
| 725 | 'xtc_threshold_textgenerationwebui': 0.1, | ||
| 726 | 'xtc_probability_textgenerationwebui': 0, | ||
| 721 | }; | 727 | }; |
| 722 | 728 | ||
| 723 | for (const [id, value] of Object.entries(inputs)) { | 729 | for (const [id, value] of Object.entries(inputs)) { |
| @@ -1156,6 +1162,8 @@ export function getTextGenGenerationData(finalPrompt, maxTokens, isImpersonate, | |||
| 1156 | 'api_server': getTextGenServer(), | 1162 | 'api_server': getTextGenServer(), |
| 1157 | 'legacy_api': settings.legacy_api && (settings.type === OOBA || settings.type === APHRODITE), | 1163 | 'legacy_api': settings.legacy_api && (settings.type === OOBA || settings.type === APHRODITE), |
| 1158 | 'sampler_order': settings.type === textgen_types.KOBOLDCPP ? settings.sampler_order : undefined, | 1164 | 'sampler_order': settings.type === textgen_types.KOBOLDCPP ? settings.sampler_order : undefined, |
| 1165 | 'xtc_threshold': settings.xtc_threshold, | ||
| 1166 | 'xtc_probability': settings.xtc_probability, | ||
| 1159 | }; | 1167 | }; |
| 1160 | const nonAphroditeParams = { | 1168 | const nonAphroditeParams = { |
| 1161 | 'rep_pen': settings.rep_pen, | 1169 | 'rep_pen': settings.rep_pen, |
| @@ -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 | ||
| @@ -4777,8 +4777,10 @@ jQuery(() => { | |||
| 4777 | world_info_min_activations = Number($(this).val()); | 4777 | world_info_min_activations = Number($(this).val()); |
| 4778 | $('#world_info_min_activations_counter').val(world_info_min_activations); | 4778 | $('#world_info_min_activations_counter').val(world_info_min_activations); |
| 4779 | 4779 | ||
| 4780 | if (world_info_min_activations !== 0) { | 4780 | if (world_info_min_activations !== 0 && world_info_max_recursion_steps !== 0) { |
| 4781 | $('#world_info_max_recursion_steps').val(0).trigger('input'); | 4781 | $('#world_info_max_recursion_steps').val(0).trigger('input'); |
| 4782 | flashHighlight($('#world_info_max_recursion_steps').parent()); // flash the other control to show it has changed | ||
| 4783 | console.info('[WI] Max recursion steps set to 0, as min activations is set to', world_info_min_activations); | ||
| 4782 | } else { | 4784 | } else { |
| 4783 | saveSettings(); | 4785 | saveSettings(); |
| 4784 | } | 4786 | } |
| @@ -4840,8 +4842,10 @@ jQuery(() => { | |||
| 4840 | $('#world_info_max_recursion_steps').on('input', function () { | 4842 | $('#world_info_max_recursion_steps').on('input', function () { |
| 4841 | world_info_max_recursion_steps = Number($(this).val()); | 4843 | world_info_max_recursion_steps = Number($(this).val()); |
| 4842 | $('#world_info_max_recursion_steps_counter').val(world_info_max_recursion_steps); | 4844 | $('#world_info_max_recursion_steps_counter').val(world_info_max_recursion_steps); |
| 4843 | if (world_info_max_recursion_steps !== 0) { | 4845 | if (world_info_max_recursion_steps !== 0 && world_info_min_activations !== 0) { |
| 4844 | $('#world_info_min_activations').val(0).trigger('input'); | 4846 | $('#world_info_min_activations').val(0).trigger('input'); |
| 4847 | flashHighlight($('#world_info_min_activations').parent()); // flash the other control to show it has changed | ||
| 4848 | console.info('[WI] Min activations set to 0, as max recursion steps is set to', world_info_max_recursion_steps); | ||
| 4845 | } else { | 4849 | } else { |
| 4846 | saveSettings(); | 4850 | saveSettings(); |
| 4847 | } | 4851 | } |
| @@ -2421,7 +2421,6 @@ input[type="file"] { | |||
| 2421 | } | 2421 | } |
| 2422 | 2422 | ||
| 2423 | #rm_print_characters_block .text_block { | 2423 | #rm_print_characters_block .text_block { |
| 2424 | height: 100%; | ||
| 2425 | width: 100%; | 2424 | width: 100%; |
| 2426 | opacity: 0.5; | 2425 | opacity: 0.5; |
| 2427 | margin: 0 auto 1px auto; | 2426 | margin: 0 auto 1px auto; |
| @@ -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(); |
| @@ -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); |
| @@ -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) { |
| @@ -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; |
| @@ -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
| @@ -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; |